题目描述比较复杂,简单来说就是给一行答案序列,再给一行猜测序列,统计有多少数字是恰好对位匹配的(Strong Match, A),有多少数字是两行里都有但是位置不同的(Weak Match, B)。
A的数目可以直接遍历一遍统计,而B的数目则需要对1-9每一个数,分别统计它们在答案序列和猜测序列里各出现多少次,取较小的那个值加给B。
之所以取较小的值,是因为假设答案行有3个1,猜测行有5个1,那么总共一定有3个1是在两行都出现的,因此要加给B。
这之后还要从B里减去A的值,即去掉同时在两行里出现又是对位匹配的数的个数,剩下的就是错位的数的个数。
#include <iostream>
using namespace std;
#define MAXN 1010
int main() {
int n, game = 0;
int answer[MAXN], guess[MAXN];
while (cin >> n && n) {
cout << "Game " << ++game << ":" << endl;
for (int i = 0; i < n; i++) {
cin >> answer[i];
}
while (1) {
int A = 0, B = 0;
for (int i = 0; i < n; i++) {
cin >> guess[i];
// 直接统计A的个数
if (guess[i] == answer[i]) A++;
}
// 正常的猜测序列不会有0,故第一位为0即可退出
if (guess[0] == 0) break;
// 对每个数字,统计它在答案序列和猜测序列中各出现了多少次
// 把较小的值加给B(注意思考为何取较小值)
for (int d = 1; d <= 9; d++) {
int sum_ans = 0, sum_gue = 0;
for (int j = 0; j < n; j++) {
if (answer[j] == d) sum_ans++;
if (guess[j] == d) sum_gue++;
}
if (sum_ans < sum_gue)
B += sum_ans;
else
B += sum_gue;
}
// 再减去A的部分就是B的正确值
B -= A;
cout << " (" << A << "," << B << ")" << endl;
}
}
}
还需要注意一点
while (cin >> n && n)
cin >> n返回的也是一个cin对象,当一个cin对象作为条件选择、循环等的控制表达式时,编译器会将其转换为真值表达式,如果cin的iostate为goodbit,则这个真值表达式的结果为真,否则为假。
输入一个非数字可以置位failbit,从而结束循环,当然这是一个非正常退出。
正常退出可以用键盘模拟产生EOF,表示流输入结束了。在windows中可以输入ctrl+z,unix/linux中则为ctrl+d。
因此当n = 0来结束输入时,cin >> n仍然会返回真值,故必须要加上 && n。
网友评论