坚果手机c语言编程软件,PAT-B1018-锤子剪刀布(C语言实现)

题目要求

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

a767434d9ded

剪刀石头布

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

输入格式

输入第 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. 寻找思路(按先处理,再分析输入和输出的顺序)

根据题目要求处理过程可以分为两个模块:

比较模块,比出甲乙两人的胜负

记录成绩模块,分别记录两人的胜负,以及出BCJ中的哪一个取胜的

显而易见,对数据的处理过程就是这两个模块反复执行的过程

对输入分析,要承载输入的数据那么需要一个int类型的N,以及两个100000大小的char数组分别保存甲乙两人每次对决的数据

对输出进行分析,首先是甲乙的胜平负次数以及获胜次数最多的手势,这个可以用变量来存储,也可以用数组来存储,我当时是用的数组,因为感觉太多变量不太好,但想想数组的实质其实就是一堆变量的集合,只不过在它们身上额外定义了一种线性关系而已,用数组和用变量都差不多的。另外,对于输出格式有要求,这说明要有一个输出格式的控制模块,最后一句如果解不唯一,则输出按字母序最小的解。说明输出时要有一个嵌套的if条件,不过我之后用数组对BCJ三个字母做了转换处理,可以避免这个嵌套的if条件句

2. 细节实现

有了一个大致的思路和框架,接下来就是各个模块的细节问题了,为了方便直接给甲乙起名叫杰瑞和汤姆,把BCJ分别转化为数字123,这样就有了天然的大小关系,小的胜大的输,只有一种情况是例外,那就是1和3放在一起比的时候,所以要加一个判断结构,把BCJ转化成数字还有一个好处,那就是直接用数组存储BCJ分别的获胜次数,用相应的数组下标来标记BCJ(下标012比123相对应少1),这样处理直接用一个temp变量从数组第一个开始比较,保存下第一个的值,只有当遇到比temp大的值时才改变temp的值,这样选出来的最大值一定是值最大且字母最小的(因为数组是按字母排序),输出时按下标对应的字母输出即可。

所以,要加一个转化模块

可以关门放代码了

#include

#define MAXSIZE 100000

int inverse(char); //转换模块

int compare(int,int); //比较模块

void output(int *); //对输出格式进行控制

void victory_max(int *); //找出获胜次数最多的那个字母

int main(){

int N;

int Jerry_choice[3]={0},Tom_choice[3]={0}; //BCJ获胜的次数

int Jerry_scores[3]={0},Tom_scores[3]={0}; //胜平负次数

int Jerry[MAXSIZE],Tom[MAXSIZE]; //两人的比赛记录

int result; //比较出来的结果

char temp_J,temp_T; //暂存BCJ以把它转换成数字

scanf("%d",&N);

for(int i=0;i

getchar(); //吃掉‘\n’,容易忽略

scanf("%c %c",&temp_J,&temp_T);

Jerry[i]=inverse(temp_J);

Tom[i]=inverse(temp_T);

}

for(int i=0;i

result=compare(Jerry[i],Tom[i]);

if(result==0){

Tom_scores[0]++;

Jerry_scores[2]++;

Tom_choice[Tom[i]-1]++; //别忘了-1,因为数组从0开始

}

else if(result==1){

Jerry_scores[0]++;

Tom_scores[2]++;

Jerry_choice[Jerry[i]-1]++;

}

else{

Jerry_scores[1]++;

Tom_scores[1]++;

}

}

output(Jerry_scores);

printf("\n");

output(Tom_scores);

printf("\n");

victory_max(Jerry_choice);

printf(" ");

victory_max(Tom_choice);

return 0;

}

int inverse(char x){

if(x=='B'){

return 1;

}

if(x=='C'){

return 2;

}

if(x=='J'){

return 3;

}

}

int compare(int Jerry,int Tom){ //Jerry赢返回1,Tom赢返回0,平返回2;

if(Jerry>Tom){

if(Jerry==3 && Tom==1){ //Tom是布,Jerry是剪刀

return 1;

}

return 0;

}

if(Jerry

if(Tom==3 && Jerry==1){

return 0;

}

return 1;

}

else{

return 2;

}

}

void output(int *p){

for(int i=0;i<3;i++){

printf("%d",p[i]);

if(i!=2){

printf(" ");

}

}

}

void victory_max(int *p){

int temp=-1,k;

for(int i=0;i<3;i++){

if(temp

temp=p[i];

k=i;

}

}

if(k==0){

printf("B");

}

if(k==1){

printf("C");

}

if(k==2){

printf("J");

}

}

写在后面

因为第二次调用scanf()时,用的是%c,所以scanf()不会忽略之前输入N时以及每个循环结束时附带的'\n',所以要用getchar()消掉'\n'这个字符

关于消掉‘\n’还有一种方法:

int recovery; //回收

for(int i=0;i

scanf("%c %c %c",&recovery,&temp_J,&temp_T);

Jerry[i]=inverse(temp_J);

Tom[i]=inverse(temp_T);

}

建立一个变量,这样可以让scanf()读入三个字符,第一个,即‘\n’,赋值给该变量,这样也可以使‘\n’不产生影响

有什么问题或文章疏漏的地方可以在下面评论中指出,也可以进入主页关注我的微信公众号

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值