1018 锤子剪刀布 (20)

大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示:

1018 锤子剪刀布 (20)_第1张图片

现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。

输入格式:

输入第 1 行给出正整数 N(≤105),即双方交锋的次数。随后 N 行,每行给出一次交锋的信息,即甲、乙双方同时给出的的手势。C 代表“锤子”、J 代表“剪刀”、B 代表“布”,第 1 个字母代表甲方,第 2 个代表乙方,中间有 1 个空格。

输出格式:

输出第 1、2 行分别给出甲、乙的胜、平、负次数,数字间以 1 个空格分隔。第 3 行给出两个字母,分别代表甲、乙获胜次数最多的手势,中间有 1 个空格。如果解不唯一,则输出按字母序最小的解。

输入样例:

10
C J
J B
C B
B B
B C
C C
C B
J B
B C
J J

输出样例:

5 3 2
2 3 5
B B

 为了使得我的代码更容易理解,所以我并没有对我的代码做出精简,但是这样看的话会让人觉得更容易理解。

#include 
using namespace std;

int main() {
    int N;
    char jia, yi;   //甲乙的出手
    int sheng_jia = 0, pin = 0, fu_jia = 0, count_jC = 0, count_jJ = 0, count_jB = 0;  // 甲的胜平负
    int sheng_yi = 0, fu_yi = 0, count_yC = 0, count_yJ = 0, count_yB = 0;
    cin >> N;

    for (int i = 0; i < N; i++) {
        cin >> jia >> yi;
        if (jia == 'C') {            //甲是锤子
            if (yi == 'C')
                pin++;
            else if (yi == 'J') {
                sheng_jia++;
                count_jC++;
                fu_yi++;
            }
            else {
                fu_jia++;
                sheng_yi++;
                count_yB++;
            }
        }
        else if (jia == 'J') {            //甲是剪刀
            if (yi == 'C') {
                fu_jia++;
                sheng_yi++;
                count_yC++;
            }
            else if (yi == 'J') {
                pin++;
            }
            else {
                sheng_jia++;
                count_jJ++;
                fu_yi++;
            }
        }
        else {                           //甲是布
            if (yi == 'C') {
                sheng_jia++;
                count_jB++;
                fu_yi++;
            }
            else if (yi == 'J') {
                fu_jia++;
                sheng_yi++;
                count_yJ++;
            }
            else {
                pin++;
            }
        }
    }
    cout << sheng_jia << " " << pin << " " << fu_jia << endl;
    cout << sheng_yi << " " << pin << " " << fu_yi << endl;

    //计算甲乙胜最高的出手是什么
    int max_count_j = max(count_jC, max(count_jB, count_jJ));
    int max_count_y = max(count_yC, max(count_yB, count_yJ));
    
     //判断甲的胜最多的出手        请注意每次判断都要判断max_count_y,因为如果是0 0 2最后会输出C而不是B
    if (max_count_j == count_jC && count_jC == count_jJ && (count_jC == count_jB || count_jJ == count_jB)) {
        cout << 'B' << " ";
    }
    else if (max_count_j == count_jC && count_jC == count_jJ) {
        cout << 'C' << " ";
    }
    else {
        if (max_count_j == count_jC)
            cout << 'C' << " ";
        else if (max_count_j == count_jB)
            cout << 'B' << " ";
        else
            cout << 'J' << " ";
    }

    //判断乙的胜最多的出手        请注意每次判断都要判断max_count_y,因为如果是0 0 2最后会输出C而不是B
    if (max_count_y == count_yC && count_yC == count_yJ && (count_yC == count_yB || count_yJ == count_yB)) {   //
        cout << 'B';
    }
    else if (max_count_y == count_yC && count_yC == count_yJ) {
        cout << 'C';
    }
    else {
        if (max_count_y == count_yC)
            cout << 'C';
        else if (max_count_y == count_yB)
            cout << 'B';
        else
            cout << 'J';
    }
    return 0;


}

我来讲解一下我的代码思路:

  首先就是变量的解释:N为甲乙对局的数量。char jia, yi就是甲乙每次对局的出手(锤子剪刀布)。int sheng_jia = 0, pin = 0, fu_jia=0则是每次甲的胜平负次数。count_jC = 0, count_jJ = 0, count_jB = 0则是甲获胜的时候出锤子剪刀布的次数,int sheng_yi = 0, fu_yi = 0则是每次乙的胜平负次数。count_yC = 0, count_yJ = 0, count_yB = 0则是乙获胜的时候出锤子剪刀布的次数。

  接着进入for循环,循环输入后,我们判断甲到底出的是锤子还是剪刀还是布,在每次判断中我们内层嵌套乙到底出的是锤子还是剪刀还是布。这样经过3次大判断中夹杂3次小判断一个9次判断我们就可以将胜负平次数以及count_jC , count_jJ, count_jB ,count_yC , count_yJ, count_yB都求出来了,然后输出甲乙的胜负平次数就好了。

  做到这,题目还要求在第三行的时候输出甲乙胜的时候出手最多的是什么,那这时候就用到了我们当时定义的count_jC , count_jJ, count_jB ,count_yC , count_yJ, count_yB了,首先我们计算max_count_j = max(count_jC, max(count_jB, count_jJ));算出甲的最大次数,max_count_y = max(count_yC, max(count_yB, count_yJ));算出乙的最大次数。但是这还不够,题目说“如果解不唯一,则输出按字母序最小的解”所以我们还要追加判断,但是要记住每次判断相等都要判断max_count因为如果是0 0 2最后会输出C而不是B。

  做到这我们就完成了对于这道题目的解决。

但是我的代码还是比较冗余的,其实我们将他简化,比如我定义了甲的胜负平次数,乙的胜负次数,其实不需要这么多,甲胜的次数其实就是乙负的次数,甲负的次数其实就是乙负的次数。但是为了更加直观易懂我还是将他写开吧。 

//精简版代码
//思路其实和第一个代码相同
#include
using namespace std;
int main()
{
    int N;
    int js = 0, jf = 0, jp = 0;//分别是甲胜、甲负、甲平
    int ys = 0, yf = 0;        //分别是乙胜、乙负、乙平等于甲平所以到时候输出甲平就可以
    int jc = 0, jb = 0, jj = 0;//分别是甲锤、甲布、甲剪
    int yc = 0, yb = 0,yj = 0; //分别是乙锤、乙布、乙剪
    char j, y;                 //表示甲乙出的手势
    cin >> N;
    for (int i = 0; i < N; i++)
    {
        cin >> j >> y;

        if(j=='C')                              //甲出锤的所有情况
        {
            if (y == 'C')jp++;
            if (y == 'B')ys++, jf++, yb++;
            if (y == 'J')yf++, js++, jc++;
        }
        if (j == 'B')                        //甲出布的所有情况
        {
            if (y == 'C') js++, yf++,jb++;
            if (y == 'B') jp++;
            if (y == 'J')jf++, ys++, yj++;
        }
        if (j == 'J')                        //甲出剪刀的所有情况
        {
            if (y == 'C')ys++, jf++, yc++;
            if (y == 'B')js++, yf++, jj++;
            if (y == 'J')jp++;
        }
    }
    cout << js <<' '<< jp<<' ' << jf << endl;   //输出甲乙的胜负记录
    cout << ys << ' '<= jc &&jb>= jj)cout << 'B';            //按字母顺序进行判断,先判断B是不是大于等于C和J
    else if (jc >= jb &&jc>= jj)cout << 'C';       //在判断C,最后判断J
    else cout << 'J';
    cout<<' ';
    if (yb >= yc&&yb >= yj)cout << 'B';             //按字母顺序进行判断,先判断B是不是大于等于C和J
    else if (yc >= yb &&yc>= yj)cout << 'C';        //在判断C,最后判断J
    else cout << 'J';
}

  所有的内容都是我逐个挨个打上去的,所以有错别字也别骂我哦,最后可以要一个小小的赞嘛。  

你可能感兴趣的:(PAT乙级刷题,算法,c++,数据结构)