uva 340 Master-Mind Hints

小結:

    題意沒讀懂,看其他人的然後結合示例看懂的,感覺網上講題意的好多都一樣,我想通過實例用較實在淺顯的語言來描述一下這個問題,希望對大家有所幫助

 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  1 2 3
a  1 3 5 5
b  1 1 2 3
c 4 3 5 5

 考慮自己的表達不好,就用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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章