UVa340 - Master-Mind Hints 题解

题目

题目地址

UVa340 - Master-Mind Hints

题目大意

实现一个经典“猜数字”游戏。给定答案序列和用户猜的序列,统计有多少数字正确(A),有多少数字在两个序列都出现过但位置不对(B)。
输入包含多组数据。每组输入第一行为序列长度n,第二行是答案序列,接下来是若干猜测序列。猜测序列全0时该组数据结束。n=0时输入结束。

样例输入

4
1 3 5 5
1 1 2 3
4 3 3 5
6 5 5 1
6 1 3 5
1 3 5 5
0 0 0 0
10
1 2 2 2 4 5 6 6 6 9
1 2 3 4 5 6 7 8 9 1
1 1 2 2 3 3 4 4 5 5
1 2 1 3 1 5 1 6 1 9
1 2 2 5 5 5 6 6 6 7
0 0 0 0 0 0 0 0 0 0
0

样例输出

Game 1:
    (1,1)
    (2,0)
    (1,2)
    (1,2)
    (4,0)
Game 2:
    (2,4)
    (3,2)
    (5,0)
    (7,0)

题解

题目分析

观察第一组输入,答案序列与第一次猜测序列为

1 3 5 5
1 1 2 3

只有第一位是相同的,所以A=1。
猜测序列里的第2位“1”为位置不对,第4位“3”同样是位置不对,所以B=2……诶不对,样例输出里的B为1。怎么回事?
是因为猜测序列第1位的“1”与答案序列第1位的“1”已经“配对”了,所以再计算B时候不能考虑已经配对的数字。所以A=1,B=1。
现在来换种思路考虑计算B。
两个序列中相同的“1”有1个(答案序列有1个,猜测序列有2个,取最小的那个),“2”有0个,“3”有1个,“5”有0个。
之前算出了A=1。现在可以算B=1+0+1+0-A。
考虑下为什么B要这样算。
Then show the code.

#include <stdio.h>

int main(){
    //注意题目中的数据范围
    int n, a[1005], b[1005], A, B, kase = 0;
    int c1, c2;

    while(scanf("%d", &n) == 1 && n){
        for(int i=0; i<n; i++){
            scanf("%d", &a[i]);
        }

        printf("Game %d:\n", ++kase);
        while(1){
            A = B = 0;
            for(int i=0; i<n; i++){
                scanf("%d", &b[i]);
            }
            //猜测序列全为0时只需要检查第一个是否为0
            if(b[0] == 0)
                break;

            for(int i=0; i<n; i++){
                if(a[i] == b[i])
                    A++;
            }
            //这里就是求B的第二种思路
            for(int d=1; d<=9; d++){
                c1 = c2 = 0;
                for(int i=0; i<n; i++){
                    if(a[i] == d) c1++;
                    if(b[i] == d) c2++;
                }

                if(c1 > c2) B += c2;
                else B += c1;
            }
            printf("    (%d,%d)\n", A, B-A);
        }

    }
    return 0;
}
posted @ 2020-10-29 21:32  1v7w  阅读(79)  评论(0编辑  收藏  举报