今天下午自己做的比赛,离AK最近的一次,其他题都非常顺利,C,E两题没做出来,E题明显的快速幂,我也知道是longlong溢出了,就是没能解决,其实就是先将n%mod再去算乘方,就少了一小行代码啊有木有。c题也不难感觉就是贪心,不过这个题没什么好说的,再给机会还够呛能A。
A | 星图 |
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
题目描述
输入描述:
单组输入。第一行三个正整数N,M,Q(1 <= N,M <= 1000,1 <= Q <= 1000000),分别表示矩阵的行列,以及询问的个数,询问之间相互独立。 然后一个N*M的矩阵,由’*’和’#’构成,表示星图。’*’表示恒星,’#’表示黑洞。 最后Q行,表示Q个询问,每行两个正整数x,y(1 <= x <= N, 1 <= y <= M)表示发光恒星的位置(从上往下数第x行,从左往右数第y列,且保证该位置一定是恒星)和一个字符p(p∈{‘L’, ‘R’, ‘D’, ‘U’},’R’表示向右;’L’表示向左;’D’表示向下’;’U’表示向上)表示该恒星产生光束的方向。
输出描述:
一共Q行。对于每个询问,若该恒星发出的光束能够进入星图之外的区域则输出“YES”;否则输出“NO”。(不包含引号)
输入
4 5 5 **##* ***** *#*#* ##**# 2 3 D 2 3 U 1 5 R 4 4 U 3 1 U
输出
YES NO YES NO YES
直接先将所有恒星发光情况处理完,否则超时
代码:
#include<iostream>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<queue>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
#define M 1005
int n,m,q;
char p[M][M];
bool ok[M][M][4]; //0->'U',1->'D',2->'L',3->'R',true->不能穿过
int main()
{
int i,j,x,y;
char op;
scanf("%d%d%d",&n,&m,&q);
for(i=0;i<n;i++)
{
scanf("%s",p[i]);
}
bool f;
for(i=0;i<n;i++)
{
f=true;
for(j=0;j<m;j++)
{
if(f==false) //对于点i,j如果它左边已经有黑洞即f==false,则往左的光线不能到达边缘,其他方向类似
ok[i][j][2]=true;
else if(p[i][j]=='#') //出现黑洞,记录下来
f=false;
}
f=true;
for(j=m-1;j>=0;j--) //观察点右侧有没有黑洞,是从右捋过来的
{
if(f==false)
ok[i][j][3]=true;
else if(p[i][j]=='#')
f=false;
}
}
for(j=0;j<m;j++)
{
f=true;
for(i=0;i<n;i++)
{
if(f==false)
ok[i][j][0]=true;
else if(p[i][j]=='#')
f=false;
}
f=true;
for(i=n-1;i>=0;i--)
{
if(f==false)
ok[i][j][1]=true;
else if(p[i][j]=='#')
f=false;
}
}
while(q--)
{
bool f=true;
scanf("%d%d %c",&x,&y,&op);
x--;y--;
if(op=='U')
{
if(ok[x][y][0]==true)
f=false;
//cout<<ok[x][y][0]<<f<<endl;
}else if(op=='D')
{
if(ok[x][y][1]==true)
f=false;
}else if(op=='L')
{
if(ok[x][y][2]==true)
f=false;
}else if(op=='R')
{
if(ok[x][y][3]==true)
f=false;
}
if(f)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
B | 好数 |
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
我们定义“好数”:对于一个正整数,若它只有0~9中的一种数字构成,我们就称其为好数。现在给你一个正整数,请判断它是否为好数。
输入描述:
单组输入。一个正整数x(1<= x <= 10100000)
输出描述:
若该数x是“好数”则输出“YES”。否则输出“NO”。(没有双引号)
输入
7777777777777777777777777777777777777888888888888888
输出
NO
输入
5555555555555555555555555555555555555555
输出
YES
输入
16146483543484318146436841468
输出
NO
注意读题是只能由0~9中一种字符构成,而不是只能由这10个字符构成
代码:
#include<iostream>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<queue>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
#define M 100010
char ch[M];
int main()
{
scanf("%s",ch);
int i,len=strlen(ch);
bool flag=true;
for(i=1;i<len;i++)
{
if(ch[i]!=ch[0])
{
flag=false;
break;
}
}
if(flag)
printf("YES\n");
else
printf("NO\n");
return 0;
}
C | 装进肚子 |
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
题目描述
输入描述:
第一行包含两个数n,K表示每天要吃的巧克力数量和要在早上吃的数量。(n <= 100000, K <= n) 第二行包含n个整数Ai(1 <= i <= n) 表示个第i个巧克力在早上吃可得到的甜蜜值 (Ai <= 100000) 第三行包含n个整数Bi(1 <= i <= n) 表示个第i个巧克力在晚上吃可得到的甜蜜值 (Bi <= 100000)
输出描述:
输出仅一行包含一个整数表示ZZZZone能获得的最大甜蜜值。
输入
2 1 3 6 2 8
输出
11
说明
早上吃第一个巧克力得到3甜蜜值,晚上吃第2个巧克力得到8的甜蜜值,所以最大可得到11的甜蜜值。
代码:
#include<iostream>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<queue>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
#define M 100005
ll n,k;
struct node{
ll a,b;
bool operator <(const node & obj) const
{
return (a-b)>(obj.a-obj.b);
}
}p[M];
int main()
{
int i;
scanf("%lld%lld",&n,&k);
for(i=1;i<=n;i++)
{
scanf("%lld",&p[i].a);
}
for(i=1;i<=n;i++)
{
scanf("%lld",&p[i].b);
}
sort(p+1,p+n+1);
ll ans=0;
for(i=1;i<=k;i++)
{
ans+=p[i].a;
}
for(i=k+1;i<=n;i++)
{
ans+=p[i].b;
}
printf("%lld\n",ans);
return 0;
}
D | ZZZZone爱吃糖 |
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
题目描述
输入描述:
第一行,一个整数n,表示有n个糖果盒子 (n <= 10000) 第二行包含n个整数,表示从下标为1到n的盒子的甜蜜值(-10000 <= wi <= 10000) 第三行包含一个整数m表示方案数 (m <= 10000) 接下来m行,每行两个整数L, R (1 <= L, R <= n)
输出描述:
输出一行,包含一个整数表示最大的甜蜜值.
输入
5 1 -2 3 -4 5 2 1 5 1 2
输出
3
说明
第一个方案从1到5可得到3的甜蜜值,第二个可以得到-1的甜蜜值(此时当然不会选这个方案),所以最大可得到3的甜蜜值
注意题意,题意不太清楚,其实这里是可以同时选多个方案
代码:
#include<iostream>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<queue>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
#define M 10005
int n,m;
int a[M];
ll sum[M];
int main()
{
int l,r,i;
ll temp,ans=0;
scanf("%d",&n);
sum[0]=0;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
scanf("%d",&m);
while(m--)
{
scanf("%d%d",&l,&r);
temp=sum[r]-sum[l-1];
if(temp>0)
ans+=temp;
}
if(ans>0)
cout<<ans<<endl;
else
cout<<0<<endl;
return 0;
}
E | 开心的涂刷 |
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
输入描述:
输入仅包含一行,包含两个数n,m分别表示格子数和颜色数。(1 <= n <= 1e12, 1 <= m <= 1e12)
输出描述:
输出一行包含一个整数,让小明开心的涂刷方案数。 答案对1000000007取模
输入
3 2
输出
6
说明
一共有(1, 1, 2), (2, 1, 1), (2, 2, 1), (1, 2, 2), (1, 1, 1), (2, 2, 2) 这6种方案
求让他开心的方案数不好求,可以先求总的方案数(m^n)再减去不开心的方案数(m*pow(m-1,n-1)),公式都是最简单的组合公式
代码:
#include<iostream>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<queue>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
#define MOD 1000000007
ll n,m;
ll pow_mod(ll n,ll k,ll mod) //快速幂求(n^p)%m的值
{
ll res=1;
n=n%mod; //比赛没加这一句就没A
while(k>0)
{
if(k&1)
res=res*n%mod;
n=n*n%mod;
k>>=1;
}
return res;
}
int main()
{
scanf("%lld%lld",&n,&m);
if(n==1)
cout<<0<<endl;
else if(m==1)
cout<<1<<endl;
else{
ll t1=pow_mod(m,n,MOD);
ll t2=((m%MOD)*pow_mod(m-1,n-1,MOD))%MOD;
cout<<(t1+MOD-t2)%MOD<<endl;
}
return 0;
}
F | 兼职数靶 |
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
1 2 2 2 2 2 2 2 2 2 2 2 1
1 2 2 2 2 2 2 2 2 2 2 2 1
1 2 2 3 3 3 3 3 3 3 2 2 1
1 2 2 3 3 3 3 3 3 3 2 2 1
1 2 2 3 3 4 4 4 3 3 2 2 1
1 2 2 3 3 4 4 4 3 3 2 2 1
1 2 2 3 3 4 4 4 3 3 2 2 1
1 2 2 3 3 3 3 3 3 3 2 2 1
1 2 2 3 3 3 3 3 3 3 2 2 1
1 2 2 2 2 2 2 2 2 2 2 2 1
1 1 1 1 1 1 1 1 1 1 1 1 1
输入描述:
第一行一个整数N(1 <= N <= 169),表示射击的次数,接着输入一个13 * 13的字符矩阵,里面只包含 '.' 和 '#','#'表示被击中,而 '.' 则表示没被击中。(保证'#'恰好有N个) 多组输入,N=0表示输入结束。
输出描述:
该运动员的平均射击环数(保留两位小数)。
输入
2 ............. ............. ............. ............. ............. ............. ......#...... ...#......... ............. ............. ............. ............. ............. 0
输出
3.50
说明
射中3环一次,4环一次,平均值为3.50。
做这个题的时间主要是来给数组赋值。。。
代码:
#include<iostream>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<queue>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
#define M 13
int n;
char m[M][M];
int main()
{
int val[13][13]={
{1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1},
{1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1},
{1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1},
{1 ,2 ,2 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,2 ,2 ,1},
{1 ,2 ,2 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,2 ,2 ,1},
{1 ,2 ,2 ,3 ,3 ,4 ,4 ,4 ,3 ,3 ,2 ,2 ,1},
{1 ,2 ,2 ,3 ,3 ,4 ,4 ,4 ,3 ,3 ,2 ,2 ,1},
{1 ,2 ,2 ,3 ,3 ,4 ,4 ,4 ,3 ,3 ,2 ,2 ,1},
{1 ,2 ,2 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,2 ,2 ,1},
{1 ,2 ,2 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,2 ,2 ,1},
{1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1},
{1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1 },
{1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1},
};
int i,j;
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break;
for(i=0;i<13;i++)
{
scanf("%s",m[i]);
}
double ans=0;
for(i=0;i<13;i++)
{
for(j=0;j<13;j++)
{
if(m[i][j]=='#')
{
ans+=1.0*val[i][j];
}
}
}
ans=ans/n;
cout<<fixed<<setprecision(2)<<ans<<endl;
}
return 0;
}
G | 卡牌游戏 |
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
中国文化的五行:金、木、水、火、土相生相克, 一天Alice和Bob玩起了卡牌游戏。卡牌包含5种类型Jin,Mu,Shui,Huo,Tu,分别代表金、木、水、火、土。
金克木,木克土,土克水,水克火,火克金。游戏规则如下:
输入描述:
第一行包含一个整数n(1 <= n <= 1000),表示两人游戏轮数。 接下来n行包含两个字符串,分别表示Alice,Bod抽到的卡牌类型 (本题为单组测评)
输出描述:
输出仅一行,如果Alice获胜输出“Alice”,Bob获胜输出“Bob”,平局输出“Draw” (本题为单组测评)
输入
3 Jin Mu Mu Jin Huo Huo
输出
Draw
做这个题的时间主要是写判断函数。。。
代码:
#include<iostream>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<queue>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
#define M 1010
int n;
string s1,s2;
int ok()
{
if(s1=="Jin")
{
if(s2=="Mu")
return 0;
if(s2=="Huo")
return 1;
return 2;
}
if(s1=="Mu")
{
if(s2=="Tu")
return 0;
if(s2=="Jin")
return 1;
return 2;
}
if(s1=="Shui")
{
if(s2=="Huo")
return 0;
if(s2=="Tu")
return 1;
return 2;
}
if(s1=="Huo")
{
if(s2=="Jin")
return 0;
if(s2=="Shui")
return 1;
return 2;
}
if(s1=="Tu")
{
if(s2=="Shui")
return 0;
if(s2=="Mu")
return 1;
return 2;
}
return 2;
}
int main()
{
scanf("%d",&n);
int i,t1=0,t2=0;
for(i=0;i<n;i++)
{
cin>>s1>>s2;
if(ok()==0) //0胜,1负,2平局
{
t1+=3;
}else if(ok()==1){
t2+=3;
}else if(ok()==2){
t1++;
t2++;
}
}
if(t1>t2)
printf("Alice\n");
else if(t1<t2)
printf("Bob\n");
else
printf("Draw\n");
return 0;
}
H | Hungry! |
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
输入描述:
The input will be multiple tests, and each line will contain an integer N (1 <= N <= 20).
输出描述:
Just observe the example.
输入
2 3
输出
gu...gu... The story is so boring. And I am so hungry! gu...gu...gu... The story is so boring. And I am so hungry!
说明
How clear the example !
做这个题的时间主要是读题。。。
代码:
#include<iostream>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<queue>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
#define M 1010
int n;
int main()
{
while(scanf("%d",&n)!=EOF){
for(int i=1;i<n;i++)
{
printf("gu...");
}
printf("gu...\n");
printf("The story is so boring. And I am so hungry!\n");
}
return 0;
}
I | 快饿死的XzzF |
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
输入描述:
一个整数N(1 <= N <= 20)。
输出描述:
满足题目所述条件的方案数。
输入
1
输出
2
输入
2
输出
3
说明
有01、10、11三种满足条件的方案。
由于不能有连续的0,所以最多有n/2个0(对于奇数最后要加上n/2+1个0的情况),对于有i个0情况,可以看做是在n-i个1形成的n-i+1个空位里插入i个0的方案数即C(n-i+1,i)
要看到n的范围不过是到20,所以组合数直接算就好,不用担心溢出啊,很开心有没有
代码:
#include<iostream>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<queue>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
#define M 1010
int n;
int c(int n,int m) //计算组合数
{
if(m==0)
return 1;
int t1=1;
for(int i=1;i<=m;i++)
t1=t1*i;
int t2=1;
for(int i=0;i<m;i++)
{
t2=t2*(n-i);
}
return t2/t1;
}
int main()
{
scanf("%d",&n);
int i,ans=0;
for(i=0;i<=n/2;i++)
{
ans+=c(n-i+1,i);
//cout<<c(n-i+1,i)<<endl;
}
if(n%2==1)
ans++;
if(n==1)
printf("2\n");
else
printf("%d\n",ans);
return 0;
}
J | 小猪佩奇练打字 |
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
输入描述:
第一行输入一个字符串S ( 1 <= |S| <= 105); 第二行输入一个数字m(1 <= m <= 105), 表示佩奇要操作m次。 之后有m行, 每行有两个字母 c1, c2 表示佩奇要把这两个键帽互换位置。
输出描述:
输出一行字符串, 即佩奇用乔治玩坏的键盘输出的实际字符串。
输入
helloworld 3 e o h z l p
输出
zoppewerpd
备注:
|S| 是字符串s长度
其实比赛时自己也没捋清关系就A了,用数组存放交换后的位置,loc[i]代表一个字母,本来loc[i]=‘a’+i,但随着交换l其实loc[i]就代表了其他字母
其实输入的第一行字符串只是提供所按的键的位置,输出对应位置下的真实字母
可以理解为数组loc的下标就是loc[a]~loc[z],操作就是交换两个下标下的存的值
代码:
#include<iostream>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<queue>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
#define M 100010
int n;
char str[M];
char a,b;
int loc[26]; //
int main()
{
char temp;
int i,it;
for(i=0;i<26;i++)
{
loc[i]=i;
}
scanf("%s",str);
cin>>n;
while(n--)
{
getchar();
scanf("%c %c",&a,&b);
it=loc[a-'a'];
loc[a-'a']=loc[b-'a'];
loc[b-'a']=it;
}
int len=strlen(str);
for(int i=0;i<len;i++)
{
printf("%c",(char)('a'+loc[str[i]-'a']));
}
return 0;
}
K | 免费WiFi |
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
输入描述:
第一行包含两个数n(1 <= n <=1000), m (1 <= m <= 100)表示今天有n个人预约, 以及路由单台最大连接个数m。 之后有n行, 第i行有两个数字 [L, R] (1 <= L <= R <= 5000) 表示第i个人预约连接WiFi的时间是从L到R。
输出描述:
输出一个数字表示TRDD最少需要开启的路由器的个数。
输入
4 1 1 5 2 7 3 4 6 9
输出
3
这个题用了树状数组的思想(区间更新,单点查询),来计算每个点上对应的预约人数,或者直接暴力应该也差不多
代码:
#include<iostream>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<queue>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
#define M 1010
int n,m;
int l[M],r[M],vis[M*5];
int main()
{
scanf("%d%d",&n,&m);
int i,ans=0;
for(i=1;i<=n;i++)
{
scanf("%d%d",&l[i],&r[i]);
}
for(i=1;i<=n;i++)
{
vis[l[i]]++;
vis[r[i]+1]--;
}
int sum=0;
for(i=1;i<=5000;i++)
{
sum+=vis[i]; //当前sum值即是点i对应的预约人数
ans=max(sum,ans);
}
int cnt=ans/m;
if(ans%m!=0)
cnt++;
printf("%d\n",cnt);
return 0;
}