大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示:现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。
输入格式
输入第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 <iostream>
using namespace std;
int change(char c){ //将三个手势对应转换为数字
if(c == 'B') return 0;
if(c == 'C') return 1;
if(c == 'J') return 2;
return -1;
}
int main(){
char mp[3] = {'B', 'C', 'J'}; //用字符数组mp[0 ~ 2]代表BCJ 方便的是在最后输出时做一个转换
//countA[0 ~ 2] 代表甲 赢平负的次数 countB 代表乙
//victoryA[0 ~ 2] 代表甲使用 布锤剪 获胜的次数 victoryB代表乙
int countA[3] = {0}, countB[3] = {0}, victoryA[3] = {0}, victoryB[3] = {0};
int n; //交锋场数
cin >> n;
char c1, c2; //输入甲 乙的 手势
int k1, k2; //k1代表 甲手势转化后的数字, k2代表乙的
for(int i = 0; i < n; i++){
cin >> c1 >> c2;
k1 = change(c1); //转化为数字
k2 = change(c2);
/*
由于设置的顺序是字典序 且恰好就是循环相克顺序,因此
k1 胜 k2 的条件就是(k1 + 1) % 3 == k2;
k1 平 k2 的条件就是 k1 == k2;
k1 k2
0 > 1 布 大 石
1 > 2 石 大 剪
2 > 0 剪 大 布
很显然我们 想要 k1 胜利的话 只有在 (k1 + 1) % 3 == k2 时条件成立(很显然我这句话也是废话QAQ)
总之我们理解 记住就好,慢慢来,一点一点积累~
*/
if((k1 + 1) % 3 == k2){
countA[0]++; //甲获胜次数 加一
countB[2]++; //乙失败次数 加一
victoryA[k1]++; //甲使用 k1 手势获胜的 次数加一
}
else if(k1 == k2){
countA[1]++; //平
countB[1]++;
}
else{
countA[2]++; //甲输
countB[0]++; //乙赢
victoryB[k2]++; //乙使用 k2 手势获胜的 次数加一
}
}
cout << countA[0] << " " << countA[1] << " " << countA[2] << endl;
cout << countB[0] << " " << countB[1] << " " << countB[2] << endl;
int max1 = 0, max2 = 0;
for(int i = 1; i < 3; i++){ //找出甲乙获胜次数最多的手势(即下标0~2 代表布锤剪)
if(victoryA[i] > victoryA[max1]) max1 = i;
if(victoryB[i] > victoryB[max2]) max2 = i;
}
cout << mp[max1] << " " << mp[max2] << endl;
//因为输出的是字符而不是数字 所以通过mp数组之前记录对应的手势 转化为BCJ
return 0;
}