23级天梯赛热身赛第一阶段题题解
1-1 最好的文档
题目描述:
有一位软件工程师说过一句很有道理的话:“Good code is its own best documentation.”(好代码本身就是最好的文档)。本题就请你直接在屏幕上输出这句话。
输入格式
本题没有输入。
输出格式
在一行中输出 Good code is its own best documentation.
代码实现
#include<stdio.h>
int main()
{
printf("Good code is its own best documentation.");//直接输出
return 0;
}
运行结果
1-2 自动编程
题目描述:
输出语句是每个程序员首先要掌握的语句。Python 的输出语句很简单,只要写一个 print(X) 即可,其中 X 是需要输出的内容。
本题就请你写一个自动编程机,对任何一个要输出的整数 N,给出输出这个整数的 Python 语句。
输入格式
输入给出一个不超过10^5 的正整数。
注意:这里输入的值得范围应考虑用long以上的类型来定义输入变量。
输出格式
在一行中打印输出这个整数的 Python 语句,其中不包含任何空格。
题目分析
开始看到题目描述可能不知道本题要干啥,其实本题就是:直接输入一个数然后在(print())的括号里加这个数再打印出来就行了。
代码实现
#include<stdio.h>
int main()
{
long x;
scanf("%ld",&x);
printf("print(%ld)\n",x);
return 0;
}
运行结果
1-3 真的恭喜你
题目描述:
当别人告诉你自己考了 x 分的时候,你要回答说:“恭喜你考了 x 分!”比如小明告诉你他考了90分,你就用汉语拼音打出来 gong xi ni kao le 90 fen!。
但是如果小明没考好,比如只考了 20 分,你也“恭喜”人家就不对了。这时候你应该安慰他说:“考了 20 分别泄气!”用汉语拼音写出来就是 kao le 20 fen bie xie qi!。
输入格式
输入在一行里给出一位小朋友的分数。这个分数是一个 0 到 100 之间的整数。
输出格式
在一行中输出你对这位小朋友说的话。如果人家考到不低于 90 分,就说 gong xi ni kao le X fen!;
如果不到 90 分,就说 kao le X fen bie xie qi!。其中 X 是小朋友输入的分数。
题目分析
本题就是输入一个数判断是否不低于90分,不低于90分输出恭喜语句;低于90分输出鼓励语句。
代码实现
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
if(n>=90)//判断是否低于90分
{
printf("gong xi ni kao le %d fen!\n",n);
}
else{
printf("kao le %d fen bie xie qi!\n",n);
}
return 0;
}
运行结果
1-4 西安距离
题目描述:
小明来到了古都西安,想去参观大唐西市!
西安的道路可以看做是与x轴或y轴垂直的直线,小明位于(a,b),而目的地位于(c,d),问最少几步可以到达。
输入格式
一行中四个整数,a,b,c,d,表示坐标为(a,b)与(c,d),这里0<=a,b,c,d<=1000。
输出格式
输出这两个点的西安距离。
题目分析
本题就给出两个坐标,计算两个坐标的横、纵坐标差值的绝对值之和。
代码实现
#include<stdio.h>
int main()
{
int a,b,c,d;
scanf("%d %d %d %d",&a,&b,&c,&d);//输入两个坐标
int m=a-c;//计算差值
int n=b-d;
if(m<0)m=-m;//差值小于0取其负数
if(n<0)n=-n;
printf("%d\n",m+n);
return 0;
}
运行结果
1-5 吉老师的回归
题目描述:
曾经在天梯赛大杀四方的吉老师决定回归天梯赛赛场啦!
为了简化题目,我们不妨假设天梯赛的每道题目可以用一个不超过 500 的、只包括可打印符号的字符串描述出来,如:Problem A: Print “Hello world!”。
众所周知,吉老师的竞赛水平非常高超,你可以认为他每道题目都会做(事实上也是……)。因此,吉老师会按照顺序看题并做题。但吉老师水平太高了,所以签到题他就懒得做了(浪费时间),具体来说,假如题目的字符串里有 qiandao 或者 easy(区分大小写)的话,吉老师看完题目就会跳过这道题目不做。
现在给定这次天梯赛总共有几道题目以及吉老师已经做完了几道题目,请你告诉大家吉老师现在正在做哪个题,或者吉老师已经把所有他打算做的题目做完了。
提醒:天梯赛有分数升级的规则,如果不做签到题可能导致团队总分不足以升级,一般的选手请千万不要学习吉老师的酷炫行为!
输入格式
输入第一行是两个正整数 N,M (1≤M≤N≤30),表示本次天梯赛有 N 道题目,吉老师现在做完了 M 道。
接下来 N 行,每行是一个符合题目描述的字符串,表示天梯赛的题目内容。吉老师会按照给出的顺序看题——第一行就是吉老师看的第一道题,第二行就是第二道,以此类推。
输出格式
在一行中输出吉老师当前正在做的题目对应的题面(即做完了 M 道题目后,吉老师正在做哪个题)。如果吉老师已经把所有他打算做的题目做完了,输出一行 Wo AK le。
题目分析
本题主要变量为N和M,先了解到N为本次比赛的题目数数量,M为吉老师已经完成的题目数量。
要注意的是,当题目名称中有“easy”或“qiaodao”的字样(注意区分大小写),吉老师会跳过这个题,不算吉老师做的题目数量,也就是M。
代码实现
#include<stdio.h>
int main()
{
int N,M;//N为总题数,M为吉老师已经做了的题
scanf("%d %d",&N,&M);
int p=0;//用来判断吉老师是否完成题目
char test[1001];//写入题目名称
getchar();//接收上面的回车
for(int i=1;i<=N;i++)
{
int q=1;//用来判断题目名称中是否有“easy”或“qiaodao”的字样
gets(test);//输入题目名称
for(int j=0;test[j]!='\0';j++)
{
//下面if和else if语句来寻找题目名称中是否有“easy”或“qiaodao”的字样
//因为“easy”或“qiaodao”是连续字符,可以用下面方式进行判断
if(test[j]=='e'&&test[j+1]=='a'&&test[j+2]=='s'&&test[j+3]=='y')
{
q=0;break;//当出现“easy”时q改变值,此题吉老师选择跳过
}
else if(test[j]=='q'&&test[j+1]=='i'&&test[j+2]=='a'&&test[j+3]=='n'&&test[j+4]=='d'&&test[j+5]=='a'&&test[j+6]=='o')
{
q=0;break;//当出现“qiandao”时q改变值,此题吉老师选择跳过
}
}
if(q==1)M--;//q为1时吉老师不跳过此题,已做题数量减1
if(M<0)
{
p = 1; //M<0时p值改变为1,来表示吉老师没有完成这套题目
break; //直接结束循环,可节省程序运行时间
}
}
if(p)//p为1时判断为真执行if语句打印应该做到的题目
{
printf("吉老师做到的题目为:");//做题时这个不写,这里只是方便区分
puts(test);
}
else//p为0时,执行else语句,吉老师完成这套题目
{
printf("Wo AK le");
}
return 0;
}
运行结果
1-6斯德哥尔摩火车上的题
题目描述:
上图是新浪微博上的一则趣闻,是瑞典斯德哥尔摩火车上的一道题,看上去是段伪代码:
s = ''
a = '1112031584'
for (i = 1; i < length(a); i++) {
if (a[i] % 2 == a[i-1] % 2) {
s += max(a[i], a[i-1])
}
}
goto_url('www.multisoft.se/' + s)
其中字符串的 + 操作是连接两个字符串的意思。所以这道题其实是让大家访问网站 www.multisoft.se/112358
(注意:比赛中千万不要访问这个网址!!!)。
当然,能通过上述算法得到 112358 的原始字符串 a 是不唯一的。本题就请你判断,两个给定的原始字符串,能否通过上述算法得到相同的输出?
输入格式
输入为两行仅由数字组成的非空字符串,长度均不超过 10^4,以回车结束。
输出格式
对两个字符串分别采用上述斯德哥尔摩火车上的算法进行处理。如果两个结果是一样的,则在一行中输出那个结果;否则分别输出各自对应的处理结果,每个占一行。题目保证输出结果不为空。
题目分析
本题需要看懂给的那串伪代码:当一个字符与其前一个字符同为奇数或者同为偶数时,s那串字符就会加这两个字符的大的那个字符,最后组成一个字符串。
本题则是给出两个字符串,按照上面方法来求出相应字符串。
知识补充
1.本题用到了strlen、strcmp函数,需要引入头文件#include<string.h>
#include<string.h>
strlen(char str);//计算字符串长度
strcmp(char str1,char str2);//比较两个字符串的大小
//一个字符一个字符比较,按ASCII码值进行比较
//第一个字符串大于第二个字符串,则返回大于0的数字
//eg:
strcmp("123","113");
//从最开始比较‘1’相同,‘2’比‘1’大返回大于0的数字(具体是啥不能确定)
//第一个字符串等于第二个字符串,则返回0
//eg:
strcmp("123","123");
//两个字符一样,则返回0
//第一个字符串小于第二个字符串,则返回小于0的数字
//eg:
strcmp("113","123");
//从最开始比较‘1’相同,‘2’比‘1’小返回于0的数字(具体是啥不能确定)
//以上对字符的比较都为ASCII码值的比较
2.数字字符减掉字符’0’时,可得到相应的数字
代码实现
#include<stdio.h>
#include<string.h>
void sdge(char x1[],char x2[]);//斯德哥尔摩火车题目上伪代码转换成c语言来写
int max(int m,int n);//返回最大值
int main()
{
char a1[10001],b1[10001];
gets(a1);//输入第一个字符串
gets(b1);//输入第二个字符串
char a2[10001],b2[10001];//用来存经过转换后得到的字符串
sdge(a1,a2);
sdge(b1,b2);
if(strcmp(a2,b2)==0)//两个字符串相同时只打印一个
{
puts(a2);
}
else//两个字符串不相同时,分别打印
{
puts(a2);
puts(b2);
}
return 0;
}
void sdge(char x1[],char x2[])//斯德哥尔摩火车题目上伪代码转换成c语言来写
{
int j=0;
for(int i=1;i<strlen(x1);i++)
{
int m=x1[i]-'0';
int n=x1[i-1]-'0';
//数字字符减掉字符'0'时,可得到相应的数字,用来求得最大值
if(m%2==n%2)
{
//同样加字符'0'时可得到对应字符,并存入对应字符组中
x2[j]=max(m,n)+'0';
j++;
}
}
x2[j] = '\0';
//最后加一个'\0'字符串结束标志,有的编译器不加最后可能会打印一些奇奇怪怪的东西
}
int max(int m,int n)//返回最大值
{
if(m>n)
return m;
else
return n;
}
运行结果
1-7 随机输一次
题目描述:
大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示:
现要求你编写一个控制赢面的程序,根据对方的出招,给出对应的赢招。但是!为了不让对方意识到你在控制结果,你需要隔 K 次输一次,其中 K 是系统设定的随机数。
输入格式
输入首先在第一行给出正整数 N(≤10),随后给出 N 个系统产生的不超过 10 的正随机数 { K1,K 2,⋯,K N},数字间以空格分隔。这意味着第 i(i=0,1,⋯,N−1)次输局之后应该隔 Ki+1次再让下一个输局。如果对方出招太多,则随机数按顺序循环使用。
例如在样例中,系统产生了 3 个随机数 {2, 4, 1},则你需要:赢 2 次,输 1 次;赢 4 次,输 1 次;赢 1 次,输 1 次;然后再次回到第 1 个随机数,赢 2 次,输 1 次。
之后每行给出对方的一次出招:“ChuiZi”代表“锤子”、“JianDao”代表“剪刀”、“Bu”代表“布”。“End”代表输入结束,这一行不要作为出招处理。输入保证对方至少出了一招。
输出格式
对每一个输入的出招,按要求输出赢或输局的招式。每招占一行。
题目分析
本题输入N为随机数的数量,之后输入N个随机数(n1,n2……)来表示每赢n次要输1次。
注意:本题输入“End”时才结束,否则随机数循环(详情看下面注释)。
本题用到的strcmp函数1-6的知识点补充中有讲解,可以回过去看看。
代码实现
#include<stdio.h>
#include<string.h>
int main()
{
int N;
scanf("%d",&N);
int n[11];
for(int i=1;i<=N;i++)scanf("%d",&n[i]);//输入N个随机值
char p[20]="00";//p为对方出招
//q为结束字符串,q1对应锤子,q2对应剪刀,q3对应布
char q[4]="End";
char q1[7]="ChuiZi";
char q2[8]="JianDao";
char q3[3]="Bu";
getchar();//接收上面的回车
int i=1;//对应随机值下标
while(1)
{
//当随机值轮过一轮后没出现“End”下标回到初始值
if(i==N+1)i=1;
for(int j=1;j<=n[i];j++)//根据随机值来循环赢的次数
{
printf("对方出招:");//便于理解,做题不需输入
gets(p);//输入对方出招
if(strcmp(q,p)==0)break;//当输入“End”结束循环
printf("我们出招:");//便于理解,做题不需输入
if(strcmp(p,q1)==0)
puts(q3);//对方出锤子,我们出布
else if(strcmp(p,q2)==0)
puts(q1);//对方出剪刀,我们出锤子
else if(strcmp(p,q3)==0)
puts(q2);//对方出布,我们出剪刀
}
if(strcmp(q,p)==0)break;//当输入“End”结束循环
printf("对方出招:");//便于理解,做题不需输入
gets(p);//赢n次后输一次
if(strcmp(q,p)==0)break;//当输入“End”结束循环
printf("我们出招:");//便于理解,做题不需输入
if(strcmp(p,q1)==0)
puts(q2);//对方出锤子,我们出剪刀
else if(strcmp(p,q2)==0)
puts(q3);//对方出剪刀,我们出布
else if(strcmp(p,q3)==0)
puts(q1);//对方出布,我们出锤子
i++;//换下一个随机值
}
return 0;
}
运行结果
1-8 天梯赛的善良
题目描述:
天梯赛是个善良的比赛。善良的命题组希望将题目难度控制在一个范围内,使得每个参赛的学生都有能做出来的题目,并且最厉害的学生也要非常努力才有可能得到高分。
于是命题组首先将编程能力划分成了 10^6个等级(太疯狂了,这是假的),然后调查了每个参赛学生的编程能力。现在请你写个程序找出所有参赛学生的最小和最大能力值,给命题组作为出题的参考。
输入格式
输入在第一行中给出一个正整数 N(≤2×10^4),即参赛学生的总数。随后一行给出 N 个不超过 10^6的正整数,是参赛学生的能力值。
输出格式
第一行输出所有参赛学生的最小能力值,以及具有这个能力值的学生人数。第二行输出所有参赛学生的最大能力值,以及具有这个能力值的学生人数。同行数字间以 1 个空格分隔,行首尾不得有多余空格。
题目分析
本题找到最大能力值和最小能力值,之后通过循环计算出最大能力值和最小能力值分别对应学生人数。
注意输入的数值范围。
代码实现
#include<stdio.h>
int main()
{
unsigned long long N;//学生总数
scanf("%llu",&N);
int p=0,q=0,max,min;
//p对应最大实力人数,q对应最小实力人数
unsigned long long n[20001];//学生实力
scanf("%llu",&n[0]);
max=n[0],min=n[0];//把第一个学生的实力值赋给max和min
for(int i=1;i<N;i++)
{
scanf("%llu",&n[i]);
if(n[i]>max)max=n[i];//找到最大实力值
if(n[i]<min)min=n[i];//找到最小实力值
}
for(int i=0;i<N;i++)
{
if(n[i]==max)p++;//得到最大实力值人数
if(n[i]==min)q++;//得到最小实力值人数
}
printf("%d %d\n%d %d\n",min,q,max,p);
return 0;
}