ECJTU-ACM-20级选拔赛
点击跳转↑
1001
注意反斜杠的转译 printf("\\");
1002
要每个人都不一样,从一开始,每个人分的的礼物加一即可,则问题转化为了:首项为1,公差为1的数列前n项和与m的大小比较
#include<stdio.h>
#include<string.h>
int main()
{
int t;
scanf("%d",&t);
long long n,m;
while(t--)
{
scanf("%lld%lld",&n,&m);
long long sum = (m+1)*m/2;
if(n>=sum)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
1003
已经限制了题目和数据,省去了对年份的判断,判断月份即可
#include<stdio.h>
#include<string.h>
int m,d,rem;
void deal()
{
if(m==1||m==3||m==5||m==7||m==8||m==10||m==12)
d-=31,m++;
else if(m==4||m==6||m==9||m==11)
d-=30,m++;
else if(m==2)
d-=28,m++;
}
int check()
{
if(m==1||m==3||m==5||m==7||m==8||m==10||m==12)
if(d<=31)
return 1;
else if(m==4||m==6||m==9||m==11)
if(d<=30)
return 1;
else if(m==2)
if(d<=28)
return 1;
return 0;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d-%d%d",&m,&d,&rem);
d += rem;
while(check()==0)
{
deal();
}
printf("2077-%02d-%02d\n",m,d);
}
return 0;
}
1004
输出n×2^m即可,注意数据类型用long long,int会爆
#include<stdio.h>
#include<string.h>
int main()
{
int t;
scanf("%d",&t);
long long a,n;
while(t--)
{
scanf("%lld%lld",&a,&n);
while(n--)
{
a*=2;
}
printf("%lld\n",a);
}
return 0;
}
1005
数据范围很吓人,但是暴力遍历,分解数字,累计即可
#include<stdio.h>
#include<string.h>
int main()
{
int n,m,num[11];
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(num,0,sizeof(num));
for(int i=n;i<=m;i++)
{
int l=i,k;
while(l)
{
k=l%10;
num[k]++;
l/=10;
}
}
for(int i=0;i<=9;i++)
{
printf("%d%c",num[i],i==9 ? '\n':' ');
}
}
return 0;
}
1006
字符串处理,对各个数字进行存储,遍历过程中对当前的数字做判断即可
#include<stdio.h>
#include<string.h>
int main()
{
int t;
scanf("%d",&t);
int num[10];
char str[200005];
while(t--)
{
memset(num,0,sizeof(num));
scanf("%s",str);
int ans=strlen(str);
for(int i=0;i<strlen(str);i++)
{
int a=str[i]-'0';
int b=10-a;
if(num[b]!=0)
num[b]--,ans-=2;
else
num[a]++;
}
printf("%d\n",ans);
}
return 0;
}
1007
思维题,推导可知,如果是两段长度不等的区间,总和要相等,其中一段必然会出现两个相等的数,那么直接取这两个数(区间长度都为1的两段)就已经满足题意了,所以问题转化成:判断序列中有没有两个位置的值相等
#include<stdio.h>
#include<string.h>
int main()
{
int n;
int a,vis[1005];
while(scanf("%d",&n)!=EOF)
{
memset(vis,0,sizeof(vis));
int flag = 0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a);
if(vis[a]!=0)
flag=1;
else
vis[a]++;
}
if(flag)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
1008
思维题,博弈(意会)
因为对于两个人来说,都要先让自己赢得多,其次才是对方赢的少。
粗略考虑:对方出手时,都不还手浪费体力,最后两个人都可以最大化获胜次数,满足题意。
特殊考虑:先手不能不出,则先手的那方必然会少一次获胜次数。
#include<stdio.h>
#include<string.h>
int main()
{
int t,x,y;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&x,&y);
printf("%d %d\n",x-1,y);
}
return 0;
}
1009
字符串加法,区别在不用进位,那么就要对最后的答案进行特殊处理和特判。
首先要删去所有前导0,例如:09对应的答案是9,0001对应的答案是1,当然,若答案全为0,也要输出0.
#include<stdio.h>
#include<string.h>
char a[200005],b[200005];
int a1[200005],b1[200005],c[200005];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s%s",a,b);
memset(a1,0,sizeof(a1));
memset(b1,0,sizeof(b1));
memset(c,0,sizeof(c));
int la=strlen(a),lb=strlen(b);
for(int i=0;i<la;i++) a1[la-1-i] = a[i]-'0';
for(int i=0;i<lb;i++) b1[lb-1-i] = b[i]-'0';
int len = la>lb ? la:lb;
for(int i=0;i<len;i++)
c[i] = (a1[i]+b1[i]) % 10;
int flag=0;
for(int i=len-1;i>=0;i--)
{
if(c[i]==0 && flag==0 && i==0)
printf("0");
if(c[i]==0 && flag==0)
continue;
flag=1;
printf("%d",c[i]);
}
printf("\n");
}
return 0;
}
1010
数学规律题,根据矩阵数字摆放规则,推导出每个位置上数字的特定公式即可
#include<stdio.h>
#include<string.h>
int main()
{
long long n,x,y,ans;
while(scanf("%lld%lld%lld",&n,&x,&y)!=EOF)
{
ans = (x+3)*x/2;
if(x+y < n)
ans += (1+2*x+y)*y/2;
else
ans += (1+2*x+(n-x-1))*(n-x-1)/2 + (3*n-x-y-2)*(x+y-n+1)/2;
printf("%lld\n",ans);
}
return 0;
}