大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则
现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。
输入格式:
输入第 1 行给出正整数 N(≤10
5
),即双方交锋的次数。随后 N 行,每行给出一次交锋的信息,即甲、乙双方同时给出的的手势。C 代表“锤子”、J 代表“剪刀”、B 代表“布”,第 1 个字母代表甲方,第 2 个代表乙方,中间有 1 个空格。
输出格式:
输出第 1、2 行分别给出甲、乙的胜、平、负次数,数字间以 1 个空格分隔。第 3 行给出两个字母,分别代表甲、乙获胜次数最多的手势,中间有 1 个空格。如果解不唯一,则输出按字母序最小的解
。
根据题目的要求,我们可以知道:
①甲胜利的次数就是乙失败的次数,甲平的次数就是乙平的次数,甲负的次数就是乙胜利的次数。因此我们只需要定义三个变量,分别表示甲胜、平、负的次数,即可实现输出两个人的胜、平、负的次数。
②获取甲乙获胜次数最多的手势,并且如果解不唯一的时候,则输出按字母序最小的解
。这时候,为了避免定义过多的变量,最后还需要逐个进行比较,这时候我们可以定义两个长度为3的数组,分别表示甲、乙三个手势的获胜次数,并且下标为0的值对应着B获胜的次数,下标为1对应C获胜的次数,下标为2对应J获胜的次数
,从而实现解不唯一的时候,按照字母序输出,而不用我们再去排序了。
通过数组获取获胜次数最多的手势的时候,有一个巨坑,一直都没有想过这里会有问题,最后还是想到了😭😭😭
对应的代码:
char getMax(int arr[],int len){
int i,max = 0,max_index = 0;
for(i = 0; i < len; i++){
/*
这样可不可以咧?哈哈,大家试过之后,就会发现有几个测试点没有办法通
过,然后可能就会一直纠结于下面的代码哪里出了问题,但实际上就是这里
出了问题。
max == 0咋一看,没有问题,但是如果这个数组的值一直是0,(也就是说
这个人一直输,这人也真够衰的),那么按照题目的要求,解不唯一的时候
按照字母序输出,如果是max == 0的话,他会一直执行,最后max_index =
2,对应J,但是实际上应该是max_index = 0,也就是B才对。所以为了避
免这种错误,不可以是max == 0进行判断。当然我们一开始不给max赋值时
0不就行了吗,这样的话,就可以避免数组的值都是0的情况了。这个是可
以,比如,将max = -1的时候,那么这里的if判断就可以使(max == -1
|| max > max)了
if(max == 0 || arr[i] > max){
max = arr[i];
max_index = i;
}
*/
if(i== 0 || arr[i] > max){
max = arr[i];
max_index = i;
}
}
switch(max_index){
case 0:
return 'B';
case 1:
return 'C';
case 2:
return 'J';
}
}
完整的代码:
#include<stdio.h>
char getMax(int arr[],int len){
int i,max = 0,max_index = 0;//这里在获取胜利次数最多的时候,需要将max初始化为-1
for(i = 0; i < len; i++){
/*
这样可不可以咧?哈哈,大家试过之后,就会发现有几个测试点没有办法通
过,然后可能就会一直纠结于下面的代码哪里出了问题,但实际上就是这里
出了问题。
max == 0咋一看,没有问题,但是如果这个数组的值一直是0,(也就是说
这个人一直输,这人也真够衰的),那么按照题目的要求,解不唯一的时候
按照字母序输出,如果是max == 0的话,他会一直执行,最后max_index = 2,对应J,但是实际上应该是max_index = 0,也就是B才对。所以为了避免这种错误,不可以是max == 0进行判断
if(max == 0 || arr[i] > max){
max = arr[i];
max_index = i;
}
*/
if(i== 0 || arr[i] > max){
max = arr[i];
max_index = i;
}
}
switch(max_index){
case 0:
return 'B';
case 1:
return 'C';
case 2:
return 'J';
}
}
int main(){
int n,i;
int win_jia,ping_jia,fu_jia;
int jia_arr[3] = {0},yi_arr[3] = {0};//表示哪个出的赢的多 0:B 1:C 2:J
char jia,yi,flag1,flag2;
scanf("%d",&n);
/*
这一步非常重要,将没有被处理过的'\n'进行缓冲,如果没有这一步,那么就会
导致下面输入字符的时候有一个字符是一个换行符,导致进行执行printf("%c
%c",jia,yi)这一步的时候,只输出一个字符,并且这个字符前面不仅换行了,
而且前面还有一个空格,有个空格还好说,因为我们的输出中就有一个空格,但
是为什么会换行,而不是输出两个字符咧?就是因为我们上次输入的候,'\n'没
有被处理,导致我们输出的第一个字符就是上次输出没有被处理的字符,所以会
换行,所以我们需要执行getChar()来处理这个字符.
*/
getchar();
win_jia = 0;
ping_jia = 0;
fu_jia = 0;
for(i = 0; i < n; i++){
scanf("%c %c",&jia,&yi);
/*
这一步用于debug,证明了getChar的作用的,如果没有这一步的化,那么就
会导致其中一个字符是一个'\n'符,没有这一步进行debug的时候,我们没
有办法及时进行修正
*/
//printf("%c %c",jia,yi);
getchar();//这一步非常重要
switch(jia){
case 'C':
if(yi == 'C'){
ping_jia++;
}else if(yi == 'J'){
win_jia++;
jia_arr[1]++;
}else if(yi == 'B'){
fu_jia++;
yi_arr[0]++;
}
break;
case 'J':
if(yi == 'C'){
fu_jia++;
yi_arr[1]++;
}else if(yi == 'J'){
ping_jia++;
}else if(yi == 'B'){
win_jia++;
jia_arr[2]++;
}
break;
case 'B':
if(yi == 'C'){
win_jia++;
jia_arr[0]++;
}else if(yi == 'J'){
fu_jia++;
yi_arr[2]++;
}else if(yi == 'B'){
ping_jia++;
}
break;
}
}
flag1 = getMax(jia_arr,3);//获取甲中获胜次数最多的手势,并且如果解不唯一的时候,按照字母序输出
flag2 = getMax(yi_arr,3);//获取乙中获胜次数最多的手势,并且如果解不唯一的时候,按照字母序输出
printf("%d %d %d\n",win_jia,ping_jia,fu_jia);
printf("%d %d %d\n",fu_jia,ping_jia,win_jia);
printf("%c %c\n",flag1,flag2);
return 0;
}
运行结果: