第五届计算机能力挑战赛国赛C语言组题解(专科组)
前言:
??前两天计算机能力挑战赛国赛结束了,拿着题做了一遍,发现难度真的不大,比省赛简单多了,只是有时候可能有的同学拿着题,没认真仔细去读,或者说紧张了导致自己发挥不好吧。以下是个人的题解,若有不足之处,欢迎指正。
第一题:最小值
题目描述
在已知的若干个整数当中,你能计算出谁最小吗?
输入格式
输入数据包含多个整数(最少1个,最多1000个),用空格隔开。
输出格式
Min=x,其中的x为输入数据中最小的那个整数。
输入样例1:
1 2 3 4 5 6
输出样例1:
Min=1
输入样例2:
200 300 150 50 80 62 75 31 2023 11 25
输出样例2:
Min=11
输入样例3:
0
输出样例3:
Min=0
思路:
??这算得上是打卡题吧,唯一一点就是如何判断输入结束,可以通过 scanf 的返回值去判定,当返回值为 EOF(文件末尾) 就表示结束了
代码:
#include<stdio.h>
int main(){
int n;
int min = 1e9;//初始化最小值为很大的数
while(scanf("%d", &n) != EOF){
min = n < min ? n : min;
}
printf("Min=%d\n",min);
return 0;
}
第二题:集合相等
题目描述
对于两个元素个数相同的集合,如果两个集合中包含的元素都是一样的,我们就说这两个集合是相等的;否则集合不等。
输入格式
第1行是一个正整数 M(M<=100),然后接下来的第2行是 M 个整数,代表集合 A(集合内没有相同元素,没有空集合)。
第3行是一个正整数 N(N<=100),然后接下来的第4行是 N 个整数,代表集合 B(集合内没有相同元素,没有空集合)。
输出格式
若两个集合相等,输出 Equal!,否则输出 Not Equal!。
输入样例1:
4
1 2 3 4
4
4 3 2 1
输出样例1:
Equal!
输入样例2:
5
1 2 3 5 4
5
4 3 2 1 0
输出样例2:
Not Equal!
输入样例3:
3
1 2 3
4
1 2 3 4
输出样例3:
Not Equal!
思路:
??这题也很简单,理解好题意就行,集合相等的条件是元素一模一样,元素个数也一样。那么我们可以利用 qsort 将两个集合都排个序,从头扫描,若某个位置上两个集合的元素不相等,就说明不相等,扫描完了都没有找到不相等的元素,则说明相等。关键点在于对 qsort 函数以及比较函数的掌握度
代码:
#include<stdio.h>
#include<stdlib.h>
int a[105], b[105];
int isOK(int a[], int b[], int p, int q);
int cmp (const void * a, const void * b);
int main(){
int m, n;
//接收
scanf("%d", &m);
for(int i = 0; i < m; i++){
scanf("%d", &a[i]);
}
scanf("%d", &n);
for(int i = 0; i < n; i++){
scanf("%d", &b[i]);
}
//排序
qsort(a, m, 4, cmp);
qsort(b, n, 4, cmp);
if(isOK(a, b, m, n)){
printf("Equal!\n");
}else {
printf("Not Equal!\n");
}
return 0;
}
//判断两个集合是否相等
int isOK(int a[], int b[], int m, int n){
if(m != n) return 0; //若元素个数都不相等则一定不相等
for(int i = 0; i < m;i ++){//i < m 或 i < n 均可
if(a[i] != b[i]) return 0;
}
return 1; //返回1一定是没有找到不相同的元素
}
//比较函数升序的常规写法,背下来即可
int cmp (const void * a, const void * b){
return ( *(int*)a - *(int*)b );
}
第三题:算术
题目描述
老师给小明布置的家庭作业是一些算术题,你能通过编程计算出结果吗?
输入格式
输入是在一行中写出的关于整数的算式,只包含加减两种运算,算式中间没有空格,算式的最后是=。
最短的算式是两个数的运算,算式最长不超过100个数,算式中的整数和运算结果不超出int型数据。
输出格式
输出算式的结果,一个整数。
输入样例1:
1+2=
输出样例1:
3
输入样例2:
1-2-3=
输出样例2:
-4
输入样例3:
1+2-3+4+5-6=
输出样例3:
3
输入样例4:
8000+10000-20000+6000=
输出样例4:
4000
思路:
??本题稍微麻烦一点,需用将整个式子当作字符串,然后逐个字符地处理,若当前字符是数字 0~9 ,那么就将计算结果存起来,若当前字符是 ‘+’ 或 ‘-’,那么将上一次的数字结果,往总和里计算
代码:
#include<stdio.h>
#include<string.h>
char all[1000];//存整个式子的字符串
int main(){
int result = 0, cnt = 0;//cnt用来记录下标
gets(all);//接收字符串
char pre_flag = '+'; //当前运算符,初始为‘+’
while(pre_flag != '='){
int sum = 0;//用来记录当前数的
while(all[cnt] >= '0' && all[cnt] <= '9'){
sum = sum * 10 + all[cnt] - '0';
cnt++;
}
//算出当前数后,就可以根据前一个运算符去运算了
if(pre_flag == '+'){
result += sum;
}else result -= sum;
//更新运算符
pre_flag = all[cnt];
cnt++;
}
printf("%d\n",result);
return 0;
}
第四题:时间
题目描述:
人生的黄金时间在青年,“一寸光阴一寸金”。学习是一种投资,而时间是最宝贵的投资资本。珍惜时间吧,用学习塑造美好的未来。已知某个时刻(以分钟为单位),你知道 n 分钟以前是什么时间吗?
输入格式输入为形如HH:MM的某一时间和一个正整数N (N<=200000)。其中HH表示小时(以24小时制表示),MM表示分钟。输出格式输出为形如HH:MM的时间,表示输入数据中时间在经过 N 分钟以前的时间。注意输出时小时和分钟时都以 2 位整数形式输出。
输入样例1:
00:00 61
输出样例1:
22:59
输入样例2:
23:59 1
输出样例2:
23:58
输入样例3:
06:00 630
输出样例3:
19:30
思路:
??本题也是一个简单题,先算出总分钟数,然后减去 N 分钟,若是一个负数,则不停加上一天的时间,直到变成整数。然后用总分钟数除以60,就得到小时数,对60取余,得到分钟数,再调整一下格式输出即可。
代码:
#include<stdio.h>
int main(){
int h, m, n;
scanf("%d:%d %d",&h, &m, &n);
m += h * 60;//计算总分钟数
m -= n; //减去 n 分钟
while(m < 0){//若是负数,则不停加一天的时间,直到变成正数
m += 24 * 60;
}
h = m / 60;//重新计算小时和分钟
m = m % 60;
//调整格式输出
if(h < 10) printf("0%d:",h);
else printf("%d:",h);
if(m < 10) printf("0%d",m);
else printf("%d",m);
return 0;
}
第五题:扑克牌
任务描述:
东北地区流行一种扑克游戏“拖拉机”,每个玩家发牌3张(不包括大小王)。
假定扑克牌中用2-14(11-14点分别代表J、Q、K、A)表示每张牌的点数,用S、H、C、D代表不同花色。代表花色的字符实为表示花色的英文单词开头字母,意义如下:黑桃(Spade)、红桃(Heart)、梅花(Club)、方块(Diamond)。
给你三张扑克牌(已去除大小王),例如:5S 6H 12C(黑桃5、红桃6、梅花Q)。请编程输出这组扑克牌的牌型名称(按最大牌型)和代表此牌型的最大牌,牌型名称及输出信息详见下方文字说明。
三张扑克牌构成的所有牌型从大到小排列如下(豹子>同花顺>顺子>同花>对子>花牌):
(1)豹子(Leopard):三张牌点数一样,如5S 5H 5C。此组牌为“黑桃5、红桃5、方块5”,牌型为“豹子5”,对应的输出是:Leopard 5。
(2)同花顺(Flush straight):三张牌同花色且点数恰好相邻,如5S 7S 6S。此组牌为“黑桃5、黑桃7、黑桃6”,牌型理解为“同花顺7”,对应输出是:Flush straight 7。
(3)顺子(Straight):三张牌点数恰好相邻,但不同花色,如10H 11D 12C。牌型理解为“顺子Q”,对应输出是:Straight Q。
(4)同花(Same kind):三张牌花色相同,点数不全相同,如8H 5H 11H。牌型理解为“同花J”,对应的输出是:Same kind J。
(5)对子(Pair):花色不全相同,仅两张牌点数相同,如11H 14C 11D。牌型理解为“对子J”,对应的输出是:Pair J。
(6)花牌(General):花色不全相同,点数全不相同,如:5D 13C 8H。牌型理解为“花牌K”,对应的输出是:General K。如:5D 14C 8H。牌型理解为“花牌A”,对应的输出是:General A。
输入格式:
输入中包括多组测试数据,其中第一行是一个整数n(1<=n<=10),代表包含n组数据。
接下来的k行中,每一行是一组测试数据(三张扑克牌)。
每组测试数据是在一行中包括三张扑克牌,两张牌之间以一个空格分隔。每张牌由数字点数和花色字符构成,例如12D代表“方块Q”。
输出格式:
按顺序输出每组测试数据的牌型,每组数据的输出单独占一行。
输入样例1
6
5S 5H 5C
5S 7S 6S
10H 11D 12C
8H 5H 11H
11H 14C 11D
5D 13C 8H
输出样例1
Leopard 5
Flush straight 7
Straight Q
Same kind J
Pair J
General K
输入样例2
5
13H 13S 13C
2D 12S 2C
14H 10S 10D
11C 12D 10S
10C 12C 11C
输出样例2
Leopard K
Pair 2
Pair 10
Straight Q
Flush straight Q
思路:
??本题因为题目内容多,看似有点难,其实题意弄清楚后也很简单,牌型无非就那几种,写几个函数去判断即可,牌需要定义成结构体。总的来说就是按照手牌点数大小去排个序,然后判断最大牌型以及对应的点数即可。
代码:
#include<stdio.h>
#include<stdlib.h>
typedef struct {//定义牌结构体
int rank; //点数
char color; //花色
} Card;
int cmp(const void *a, const void *b){//按牌点数从小到大排序,
Card *m = (Card *) a;
Card *n = (Card *) b;
return m->rank - n->rank;
}
int isLeopard(Card hand[]){//豹子判断
return hand[0].rank==hand[1].rank&&hand[1].rank==hand[2].rank;
}
int isStraight(Card hand[]){//顺子判断
return hand[0].rank+1==hand[1].rank&&hand[1].rank+1==hand[2].rank;
}
int isSamekind(Card hand[]){//同花判断
return hand[0].color==hand[1].color&&hand[1].color==hand[2].color;
}
int isFlushStraight(Card hand[]){//同花顺判断
return isStraight(hand) && isSamekind(hand);
}
int isPair(Card hand[]){//对子判断
return hand[0].rank==hand[1].rank||hand[1].rank==hand[2].rank;
}
int main(){
int n;
scanf("%d", &n);
while(n-- > 0){
Card hand[3];
scanf("%d%c %d%c %d%c",&hand[0].rank,&hand[0].color,
&hand[1].rank,&hand[1].color,&hand[2].rank,&hand[2].color);
qsort(hand, 3, sizeof(Card), cmp);
//先输出牌型,牌型只有一种,优先级从高到低判断
if(isLeopard(hand)){
printf("Leopard ");
} else if(isFlushStraight(hand)){
printf("Flush straight ");
} else if(isStraight(hand)){
printf("Straight ");
} else if(isSamekind(hand)){
printf("Same kind ");
} else if(isPair(hand)){
printf("Pair ");
} else printf("General ");
//最大牌型的点数
int lastRank = hand[2].rank;
//若是对子,最大牌型的点数可以是前两个,所以对子的最大牌型点数不一定是最大点数
if(isPair(hand)) lastRank = hand[1].rank;
//输出点数
if(lastRank <= 10) printf("%d\n",lastRank);
else if(lastRank == 11) printf("J\n");
else if(lastRank == 12) printf("Q\n");
else printf("K\n");
}
return 0;
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!