写在最前:
校赛之后感觉我这名次基本上与校集训队无缘了。今天在oj的竞赛列表上看到校队的人发出了一个限时一天的公开赛。本来今天想着好好摆一天烂,但看着题好像也不是特别难,再加上心里有点不甘吧,就花了一个下午加晚上的时间去参与了一下。共六题,前四题中规中矩;第五上了点难度,不过是一种经典的蛇形填数,应该在各大竞赛书里都有收录这种问题;第六题。。目前不会,明年再来看看。
1001:
描述
给定一个k位整数N = dk-1*10k-1 + ... + d1*101 + d0 (0<=di<=9, i=0,...,k-1, dk-1>0),请编写程序统计每种不同的个位数字出现的次数。例如:给定N = 100311,则有2个0,3个1,和1个3。
输入
每个输入包含1个测试用例,即一个不超过1000位的正整数N。
输出
对N中每一种不同的个位数字,以D:M的格式在一行中输出该位数字D及其在N中出现的次数M。要求按D的升序输出。
样例输入
100311
样例输出
0:2
1:3
3:1
题目要求输入不超过1000位,很显然要用字符数组来储存数据了。
在这里我将输入的数一个一个分开,一个一个比对,这样最方便(来自校赛的教训)。字符和整型之间的转换只需要将字符减0即可。
(昨天的校赛第一题,WA和AC这两个字符串与输入进行比较,后来去问了同学才知道把两个字母分开逐个比对,非常方便。当时我还是刻板思维,用了一个strcmp把两个字母放一起比对,一直在runtime error,第一题提交了21遍还是没过。。。泪洒机房)
#include <stdio.h>
int main() {
char c;
int a[10] = {0};
int x,i;
while((c=getchar())!='\n')
{
x=c-'0';
a[x]+=1;
}
for (i = 0; i < 10; ++i)
{
if (a[i]>0)
printf("%d:%d\n", i, a[i]);
}
return 0;
}
1002
描述
编程团体赛的规则为:每个参赛队由若干队员组成;所有队员独立比赛;参赛队的成绩为所有队员的成绩和;成绩最高的队获胜。
现给定所有队员的比赛成绩,请你编写程序找出冠军队。
输入
输入第一行给出一个正整数N(<=10000),即所有参赛队员总数。随后N行,每行给出一位队员的成绩,格式为:“队伍编号-队员编号 成绩”,其中“队伍编号”为1到1000的正整数,“队员编号”为1到10的正整数,“成绩”为0到100的整数。
输出
在一行中输出冠军队的编号和总成绩,其间以一个空格分隔。注意:题目保证冠军队是唯一的。
样例输入
6
3-10 99
11-5 87
102-1 0
102-3 100
11-9 89
3-2 61
样例输出
11 176
队员编号在这道题里没有用。
我自己的这个方法我自己都觉得笨,队伍编号在1000以内那就直接造一个1000大小的数组无脑遍历,做是能做出来,但是在运行时间上和空间占用上并没有优势。
#include<string.h>
#include<stdio.h>
#define maxn 1001
int main()
{
int n,i,j=0,k,a[maxn],s[maxn],t,p,fs,max;
memset(a,0,sizeof(a));
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d-%d",&t,&p);
scanf("%d",&fs);
a[t]+=fs;
}
max=a[0];
for(i=1;i<=1000;i++)
{
if(a[i]>max)
{
max=a[i];
k=i;
}
}
printf("%d %d",k,max);
return 0;
}
(注:排名第一意味着罚时最少,本题共34人,我排名23,没啥优势)
1003
描述
给定一个长度不超过10000的、仅由英文字母构成的字符串。请将字符重新调整顺序,按“PATestPATest....”这样的顺序输出,并忽略其它字符。当然,六种字符的个数不一定是一样多的,若某种字符已经输出完,则余下的字符仍按PATest的顺序打印,直到所有字符都被输出。
输入
输入在一行中给出一个长度不超过10000的、仅由英文字母构成的非空字符串。
输出
在一行中按题目要求输出排序后的字符串。题目保证输出非空。
样例输入
redlesPayBestPATTopTeePHPereatitAPPT
样例输出
PATestPATestPTetPTePePee
个人感觉这题蛮有意思的。输入就好像是把不同面值的纸币随意摊在桌上给你,你把钱拿过来放在钱包,然后你一张一张整整齐齐的拿出来摆好,拿一张,钱包里对应的纸币就少一张。做法很简单粗暴,就不多解释了。
但还是那句话,这种做法做是能做出来,但是在时间和空间上没什么优势。
#include<stdio.h>
#include<string.h>
#define maxn 10001
int main()
{
char str[6]={'P','A','T','e','s','t'};
char c[maxn];
int i,j,k,p=0,a=0,T=0,e=0,s=0,t=0;
gets(c);
for(i=0;i<strlen(c);i++)
{
if(c[i]=='P')
p++;
else if(c[i]=='A')
a++;
else if(c[i]=='T')
T++;
else if(c[i]=='e')
e++;
else if(c[i]=='s')
s++;
else if(c[i]=='t')
t++;
}
while(p!=0||a!=0||T!=0||e!=0||s!=0||t!=0)
{
if(p!=0)
{
printf("P");
p--;
}
if(a!=0)
{
printf("A");
a--;
}
if(T!=0)
{
printf("T");
T--;
}
if(e!=0)
{
printf("e");
e--;
}
if(s!=0)
{
printf("s");
s--;
}
if(t!=0)
{
printf("t");
t--;
}
}
return 0;
}
(本题共34人,我排名22)
1004
描述
本题要求读入N名学生的成绩,将获得某一给定分数的学生人数输出。
输入
输入在第1行给出不超过105的正整数N,即学生总人数。随后1行给出N名学生的百分制整数成绩,中间以空格分隔。最后1行给出要查询的分数个数K(不超过N的正整数),随后是K个分数,中间以空格分隔。
输出
在一行中按查询顺序给出得分等于指定分数的学生人数,中间以空格分隔,但行末不得有多余空格。
样例输入
10
60 75 90 55 75 99 82 90 75 50
3 75 90 88
样例输出
3 2 0
不用在意分数的值,把分数当成下标,直接输出数组元素即可。
#include<stdio.h>
int main()
{
int a[101]={ 0 };
int n=0,i,score=0;
scanf("%d",&n);
for (i=0;i<n;i++)
{
scanf("%d",&score);
a[score]++;
}
int K;
int score1;
scanf("%d",& K);
for (i=0;i<K;i++)
{
scanf("%d",&score1);
if (i==K-1)
{
printf("%d",a[score1]);
}
else
{
printf("%d ",a[score1]);
}
}
}
1005
描述
本题要求将给定的N个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第1个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为m行n列,满足条件:m*n等于N;m>=n;且m-n取所有可能值中的最小值。
输入
输入在第1行中给出一个正整数N,第2行给出N个待填充的正整数。所有数字不超过104,相邻数字以空格分隔。
输出
输出螺旋矩阵。每行n个数字,共m行。相邻数字以1个空格分隔,行末不得有多余空格。
样例输入
12
37 76 20 98 76 42 53 95 60 81 58 93
样例输出
98 95 93
42 37 81
53 20 76
58 60 76
一道经典的蛇形填数题。做这道题之前也是把我许久没打开的算法书翻了出来。
这题目主要分为三个步骤:找规格、输入排序和打印。
在找规格中,题目明确定义了m大于n,那么将total先开根号,向上取整,让m向上走,通过判断能否整除来寻找n。
#include<stdio.h>
#include<math.h>
#include<string.h>
#define maxn 10001
void sort(int a[],int n)
{
int i,j,t;
for(i=1;i<n;i++)
{
for(j=0;j<n-1;j++)
{
if(a[j]<a[j+1])
{
t=a[j+1];
a[j+1]=a[j];
a[j]=t;
}
}
}
}
int main()
{
int total;//输入数据总个数
scanf("%d",&total);
int i,a[maxn],b[maxn][100]={0};;//记录数据大小
for(i=0;i<total;i++)
scanf("%d",&a[i]);
int j,t,flag=1;//冒泡排序,从大到小
sort(a,total);
int m,n,p,q,k,min=total-1;
for(m=ceil(sqrt(total));m>=1;m++)
{
if(total%m==0)
{
n=total/m;
break;
}
}
p=0,q=0,k=0;
while(k<total)//顺时针排序
{
while(q<n&&!b[p][q])
b[p][q++]=a[k++];
p++;
q--;
while(p<m&&!b[p][q])
b[p++][q]=a[k++];
p--;
q--;
while(q>=0&&!b[p][q])
b[p][q--]=a[k++];
p--;
q++;
while(p>=0&&!b[p][q])
b[p--][q]=a[k++];
p++;
q++;
}
for(p=0;p<m;p++)
{
for(q=0;q<n;q++)
{
if(q==n-1)
printf("%d\n",b[p][q]);
else
printf("%d ",b[p][q]);
}
}
}
在打印过程中,通过下标的加减,对应了书上讲的“笔”来进行操作
就拿第一个while循环来解释一下:
刚开始的时候我们对整个二维数组b进行了初始化,也就是说,二维数组里面全都是0。
那么,while成立的条件是,q小于n(不能超过列的边界)并且b[p][q]==0(表示即将落笔的位置是空的,未曾落笔)。
欢迎在评论区、私信交流!