猜数字游戏的提示 (Master-Mind Hints, UVa 340)

题目:

实现一个经典"猜数字"游戏。 给定答案序列和用户猜的序列,统计有多少数字位置正确
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

样例输出:
Game 1:
(1,1)
(2,0)
(1,2)
(1,2)
(4,0)
Game 2:
(2,4)
(3,2)
(5,0)
(7,0) 

代码:

 1 #include<stdio.h>
 2 #define maxn 1000
 3 
 4 int a[maxn];
 5 int b[maxn];
 6 int main()
 7 {
 8     int count(0),n(1000);
 9     while(scanf("%d",&n) == 1 && n)
10     {
11         int A(0), B(0);
12         count++;                       //用来记录是第几次游戏
13         printf("Game %d:\n",count);    
14         for(int i = 0; i < n; i++)
15             scanf("%d",&a[i]);         //读取答案序列
16         for(;;)
17         {
18             A = 0; B = 0;
19             for( i = 0; i < n; i++)
20                 scanf("%d",&b[i]);         //读取猜测序列
21             if ( b[0] == 0) break;
22             for( i = 0; i < n; i++)
23             {
24                 if (a[i] == b[i]) A++;     //判断撞库且位置正确的数量
25             }
26             for (i = 1; i <=9; i++)
27             {
28                 int index1(0),index2(0);
29                 for(int j = 0; j <n; j++)
30                 {
31                     if (a[j] == i) index1++;
32                     if (b[j] == i) index2++;
33                 }
34                 if(index1 < index2) B += index1;
35                 else B += index2;           //判断撞库的总数量
36             }
37             printf("(%d,%d)\n",A,B-A);
38         }
39     }
40     return 0;
41 }

其中在我写的时候,我觉得有几个地方需要注意:

  1. scanf("%d",&a[i])  其中&符号容易漏掉,虽然a是一个指针,可是a[i]却是一个value.
  2. 由于循环的嵌套比较多,所以要仔细检查一下哪些变量需要在某个循环的一开始就初始化,例如这里的A和B在每次判断撞库的一开始就要初始化,这方面的问题排查需要挺多的时间的
  3. 关于B(这里先定义为撞库的总数)的计算刚开始的时候很令人费解,在这个程序里面采用的是相同的数字,库与猜测方都进行比对,并得出数量。很明显如果库里这个数字的出现次数高于猜测方提供的数字里这个数字的次数直接的结果是B要加上这较小的数(因为无论如何猜测方猜到的同一个数字的数量不会超过这个数字出现的上限,这个可以画一个图就能明白)。经过从1到9的循环,最终的B就是总次数。
  4. 这样计算B的方式的式子简单但是理解有点不尽人意,当我们一个人站在这两行数字面前的时候,你想要对比数字大多数人会选择什么呢?对于我来说,应该是从库里依次选数字到猜测的数字里面去看对上了几个。不过这样的话,需要每次判断库里的数字有没有与之前重复的,举个例子库是 1 3 5 5 而如果你猜的是 4 3 3 5,那么这里的B是2而不是3,因为在1 3 5 5中最后两个数字是一样的,有一样的数字就需要排除。因此我给出的代码如下:
        for (i = 0; i < n;i++)
                    {
    
                        int flag = 1;
                        if ( i > 0 )
                            for(int min = 0; min < i; min++)
                            {
                               if(a[i] == a[min]) flag = 0;
    
                            }
                        if (flag == 1)    
                            for (int j = 0; j < n;j ++)
                            {
                                if(a[i] == b[j]) {B++;break;}
                            }
                    
                    }
    View Code

     

    使用一个标签来判断是否有相同的,有相同的数字就跳过这个数字。

这个题目我看了好久好久才看懂题目,语文不好可真令人费解╮(╯▽╰)╭

posted @ 2018-08-01 01:31  ClarkQian  阅读(270)  评论(0编辑  收藏  举报