pat乙级1018 锤子剪刀布 (20分)

该博客主要介绍了PAT乙级编程竞赛中的一道题目——锤子剪刀布。博主详细讲解了题目的输入输出格式,以及如何通过建立输赢矩阵和编写代码来统计双方的胜平负次数,并找出获胜手势。解题思路包括构建输赢矩阵,创建记录数据的类,以及遍历输入并输出结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:

https://pintia.cn/problem-sets/994805260223102976/problems/994805304020025344

题目:

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

FigCJB.jpg

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

输入格式:

输入第 1 行给出正整数 N(≤10​5​​),即双方交锋的次数。随后 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

解题思路:

1、首先打表记录石头剪刀布的输赢矩阵,胜为1,平手为0,负为-1。按照“BCJ”来构建矩阵:

[     0,1,-1

     -1 0 1

      1 -1 0]

2、构建People类记录获胜、输赢、平局次数,获胜的手势次数。

3、逐一输入,得到结果输出即可。

解题代码:

#include <bits/stdc++.h>
#define rep(i,s,e) for(int i = s;i<e;i++)
using namespace std;
const int maxsize = 100001;
class People{
public:
    void init();
    void win(char sg){
        int sn = getNumSg(sg);
        numWin[sn]++;
       // cout<<"获胜"<<sgment[sn]<<endl;
        wi++;
    }
    void lose(){
        lo++;
    }
    void draw(){
        dr++;
    }
    void judgeWin(char sg1,char sg2);
    int getNumSg(char sg);
    void print();
    void sit();//输出结果
private:
    int numWin[3];
    int lo = 0;
    int dr = 0;
    int wi = 0;
    char sgment[5] ="BCJ\0";
    int mp[3][3]={{0,1,-1},{-1,0,1},{1,-1,0}};
    int ret = 0;
};
void People::init(){
    memset(numWin,0,sizeof(numWin));
}
void People::judgeWin(char sg1,char sg2){
    // c>j,j>b,b>c
    int n1 = getNumSg(sg1);
    int n2 = getNumSg(sg2);
    int ret = mp[n1][n2];
    if(ret==1){
        win(sg1);
    }else if(ret==0){
        draw();
    }else{
        lose();
    }
}
void People::print(){
    int n1 = numWin[0];
    ret = 0;
    for(int i = 1;i<3;i++){
        if(n1<numWin[i]){
            n1 = numWin[i];
            ret = i;
        }
    }
    cout<<sgment[ret];
}
void People::sit(){
    cout<<wi<<" "<<dr<<" "<<lo;
}
int People::getNumSg(char sg){
    rep(i,0,3){
        if(sgment[i]==sg){
            return i;
        }
    }
    return 0;
}
int main()
{
    People A,B;
    A.init();
    B.init();
    char sg1,sg2;
    int n;
    cin>>n;
    rep(i,0,n)
    {
        cin>>sg1>>sg2;
        A.judgeWin(sg1,sg2);
        B.judgeWin(sg2,sg1);
    }
    A.sit();
    cout<<endl;
    B.sit();
    cout<<endl;
    A.print();
    cout<<" ";
    B.print();
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值