uva 340 Master-Mind Hints

来源:互联网 发布:淘宝电子手表 编辑:程序博客网 时间:2024/04/30 13:37

小结:

    题意没读懂,看其他人的然后结合示例看懂的,感觉网上讲题意的好多都一样,我想通过实例用较实在浅显的语言来描述一下这个问题,希望对大家有所帮助

 4
1 3 5 5         a


1 1 2 3         b        (1,1)
4 3 3 5         c         (2,0)
6 5 5 1         d         (1,2)
6 1 3 5         e         (1,2)
1 3 5 5         f          (1,2)
0 0 0 0

 题意: a行是设计者出的密码 ,下面几行都是破译者给出的猜想,将下面每次猜想的那行密码一次与a行代码比较,先比较所有strong的,也就是两行不但值一样,且位置都一样,发现一个就加一,得到的数就是括号里第一个数字,注意,每行猜想的密码与a行代码比较时,每个位置的数字只能使用一次,所以最好用两个标记数组来记录一下密码的使用状况,接着就算weak的值,也就是两行值一样,但位置却不同且每个位置都还没标记过的,发现一个就加一,值就是括号里第二个的大小。

 

  i  0 123a 1355b 1123c4355

 考虑自己的表达不好,就用b行和c行来说明一下

b行的strong和weak值分别就是括号里的两个数,strong的那个1是(a.0) (b.0),weak是 (a.1)(b.3)

c行strong值有两个,一个是 (a,1)(c,1),另一个是 (a.3)(c.3)没有符合weak要求的

 

我擦,原来以为表达一下很容易,想不到这么累,哎,语文差啊

下面时我的代码,提交时出现了runtime error,经小杨同学提醒,出现这个错误一般都是数组越界引起的,以后记牢嘞

 

#include <stdio.h>#include <stdlib.h>const int MAXN = 100000;int main( ){    int code_len,games = 0;    int s[MAXN],g[MAXN];           while (scanf("%d",&code_len) == 1){          if ( !code_len ) break;          printf("Game %d:\n",++games);                    int i,j;          for ( i = 0; i < code_len; i++)              scanf("%d",&s[i]);                           int s_mark[MAXN],g_mark[MAXN];          for (;;){              int sum = 0;              int strong= 0,weak = 0;               for ( i = 0; i < code_len; i++){                  scanf("%d",&g[i]);                  sum += g[i];                  }              if ( sum == 0) break;    //作为都输出 0 的判断条件                             memset(s_mark,0,sizeof(s_mark));              memset(g_mark,0,sizeof(g_mark)); //注意每轮比较时都要清零                             for (  i = 0; i < code_len; i++){   // 计算 strong的值                   for(  j = 0; j < code_len; j++){                       if ( !s_mark[j] && !g_mark[i] ){                           if (g[i] == s[j] && i == j)                              { s_mark[j] = 1; g_mark[i] = 1; strong++; break;}                          //if (g[i] == s[j] && i != j)                            //   { s_mark[j] = 1; g_mark[i] = 1; weak++; break;}                              // 一开始是放在这边的,后来发现是个BUG啊                           }                       }                  }                                for (  i = 0; i < code_len; i++){ //计算weak 的值  而且这两个                   for(  j = 0; j < code_len; j++){                       if ( !s_mark[j] && !g_mark[i] ){                           if (g[i] == s[j] && i != j)                               { s_mark[j] = 1; g_mark[i] = 1; weak++; break;}                          }                       }                  }                    printf("    (%d,%d)\n",strong,weak);              }          }  return 0;}

同样给出一个漂亮的代码的链接,很精简,有一些小的技巧,对题目条件的利用,比如密码都是为1 到 9 ,当比较过后将值都设为0,就没必要两外设置标记数组,但是每次都要复制密码,总的来说,内存开销还是小了,值得学习

http://www.cppblog.com/rakerichard/archive/2011/04/09/143775.html

原创粉丝点击