340 - Master-Mind Hints

340 - Master-Mind Hints_第1张图片
340 - Master-Mind Hints_第2张图片
Problem.png

题目描述比较复杂,简单来说就是给一行答案序列,再给一行猜测序列,统计有多少数字是恰好对位匹配的(Strong Match, A),有多少数字是两行里都有但是位置不同的(Weak Match, B)。
A的数目可以直接遍历一遍统计,而B的数目则需要对1-9每一个数,分别统计它们在答案序列和猜测序列里各出现多少次,取较小的那个值加给B。
之所以取较小的值,是因为假设答案行有3个1,猜测行有5个1,那么总共一定有3个1是在两行都出现的,因此要加给B。
这之后还要从B里减去A的值,即去掉同时在两行里出现又是对位匹配的数的个数,剩下的就是错位的数的个数。

#include 

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。

你可能感兴趣的:(340 - Master-Mind Hints)