PAT 锤子剪刀布

大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则
在这里插入图片描述
现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。

输入格式:
输入第 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;
}

运行结果:
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值