原题:https://pintia.cn/problem-sets/994805260223102976/problems/994805304020025344
大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示:
现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。
输入格式:
输入第 1 行给出正整数 N(
≤
1
0
5
≤10^{5}
≤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
题目分析:
按照剪刀石头布的规则,以甲的角度来计算胜、平、负的次数;获胜次数最多的手势和失败次数最多的手势。唯一需要注意的是,解不唯一时,则输出按字母序
最小的解,即输出优先级"BCJ"。
代码:
风格1:
#include<iostream>
using namespace std;
//给出A和B出的手势,返回猜拳结果
//0表示平局,1表示A赢,-1表示A输
int result(char A, char B) {
if (A == B) return 0;
else if ((A == 'C' && B == 'J') || (A == 'J' && B == 'B') || (A == 'B' && B == 'C')) return 1;
else return -1;
}
int main() {
//以A的角度来计算胜、平、负的次数;
//获胜次数最多的手势和失败次数最多的手势
int n;
cin >> n;
int times[3] = { 0,0,0, }; //胜、平、负的次数;
int vc, vj, vb; //各手势胜利的次数
int dc, dj, db; //各手势失败的次数
vc = vj = vb = 0;
dc = dj = db = 0;
char A, B; //A和B出的手势
while (n--) {
cin >> A >> B;
int r = result(A, B);
if (r == 0) times[1]++;
else if (r == 1) {
times[0]++;
if (A == 'C') vc++;
else if (A == 'J') vj++;
else vb++;
}
else {
times[2]++;
if (A == 'C') dc++;
else if (A == 'J') dj++;
else db++;
}
}
//输出胜,平,负
cout << times[0] << " " << times[1] << " " << times[2] << endl;//甲
cout << times[2] << " " << times[1] << " " << times[0] << endl;//乙
//甲获胜最多的手势
if (vb >= vc && vb >= vj) cout << "B ";
else if (vc > vb && vc >= vj) cout << "C ";
else cout << "J ";
//乙获胜最多的手势,甲输的最多的手势的对立就是乙赢得最多的手势
if (dc >= db && dc >= dj) cout << "B\n";
else if (dj > db && dj >= db) cout << "C\n";
else cout << "J\n";
system("pause");
return 0;
}
风格2:使用数组统一变量
#include<iostream>
using namespace std;
int main() {
//以A的角度来计算胜、平、负的次数;
//获胜次数最多的手势和失败次数最多的手势
int n;
cin >> n;
int times[2] = { 0}; //胜、负的次数;
int victory[3] = {0}; //各手势胜利的次数。0:B 1:C 2:J 按字符序
int defeat[3] = {0}; //各手势失败的次数(乙胜利)。0:B 1:C 2:J
char A, B; //A和B出的手势
for (int i = 0; i < n;i++) {
cin >> A >> B;
if (A == B) {
continue;//平局
}else if (A == 'C' && B == 'J') {
times[0]++;
victory[1]++;
}else if (A == 'J' && B == 'B') {
times[0]++;
victory[2]++;
}else if (A == 'B' && B == 'C') {
times[0]++;
victory[0]++;
}
else { //乙赢
times[1]++;
if (B == 'C') defeat[1]++;
else if (B == 'J') defeat[2]++;
else if (B == 'B') defeat[0]++;
}
}
//输出胜,平,负
cout << times[0] << " " << n - times[0] - times[1] << " " << times[1] << endl;//甲
cout << times[1] << " " << n - times[0] - times[1] << " " << times[0] << endl;//甲
//甲获胜最多的手势
int maxjia = victory[0] >= victory[1] ? 0 : 1;
maxjia = victory[maxjia] >= victory[2] ? maxjia : 2;
//乙获胜最多的手势,甲输的最多的手势的对立就是乙赢得最多的手势
int maxyi = defeat[0] >= defeat[1] ? 0 : 1;
maxyi = defeat[maxyi] >= defeat[2] ? maxyi : 2;
char gesture[4] = { "BCJ" }; //省略'\n'
cout << gesture[maxjia] << " " << gesture[maxyi] << endl;
system("pause");
return 0;
}