伊莉討論區

標題: 數獨 [打印本頁]

作者: andrew33673367    時間: 2014-3-13 12:52 AM     標題: 數獨

本帖最後由 andrew33673367 於 2014-3-14 12:41 AM 編輯

輸入的每一組測試資料均為 9 × 9 的矩陣,且全部為 1~9 的數字,每兩組九宮格之間以一空行作為分隔
輸出說明 :
yes or no
範例輸入 :
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9 1
3 4 5 6 7 8 9 1 2
4 5 6 7 8 9 1 2 3
5 6 7 8 9 1 2 3 4
6 7 8 9 1 2 3 4 5
7 8 9 1 2 3 4 5 6
8 9 1 2 3 4 5 6 7
9 1 2 3 4 5 6 7 8

1 9 3 2 6 5 4 7 8
7 8 2 3 1 4 9 5 6
4 5 6 9 7 8 1 3 2
2 3 4 8 5 1 6 9 7
9 6 5 4 3 7 2 8 1
8 7 1 6 9 2 3 4 5
3 1 9 5 8 6 7 2 4
5 2 7 1 4 3 8 6 9
6 4 8 7 2 9 5 1 3
範例輸出 :

no
yes



以下是我的程式碼,怎麼跑都是yes;

  1. #include <iostream>
  2. #include <cmath>
  3. #include<stdio.h>
  4. #include<stdlib.h>

  5. using namespace std;
  6. int i,j,k,n,c,d;
  7. int z,x,h;
  8. void aaa();

  9. int st[9][9];
  10. int m[9];
  11. int main()
  12. {
  13.         
  14.         c=0;
  15.         for(d=0;d<9;d++){
  16.                 m[d]=0;
  17.         }
  18.         for(z=0;z<9;z++){
  19.                 for(x=0;x<9;x++){
  20.                         cin>>st[z][x];
  21.                 }
  22.         }
  23.         aaa();
  24.         for(h=0;h<9;h++){
  25.                 if(m[h]>=2){
  26.                         cout<<"no";
  27.                         return 0;
  28.                 }
  29.         }
  30.         cout<<"yes";
  31.         return 0;
  32. }


  33. void aaa()
  34. {
  35.         for(i=0;i<9;i+=3){
  36.                 for(j=0;j<9;j+=3){
  37.                         for(k=i;k<3;k++){
  38.                                 for(n=j;n<3;n++){
  39.                                         if(st[0][0]==st[k][n]){
  40.                                                 m[c]=m[c]+1;
  41.                                         }
  42.                                 }
  43.                         }
  44.                         c=c+1;
  45.                 }
  46.         }
  47. }
複製代碼

請問是哪裡有問題??
作者: 皇臾    時間: 2014-3-13 08:15 AM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: EdisonX    時間: 2014-3-13 12:40 PM

  1. **********************************************************************************/
  2. /*  Problem: a016 "數獨(SUDOKU)"                                                */
  3. /*  Language: C (844 Bytes)                                                       */
  4. /*  Result: AC(2ms, 240KB) judge by zeroserver@ZeroJudge                          */
  5. /*  Author: edisonx at 2011-07-11 16:43:34                                        */
  6. /**********************************************************************************/


  7. #include <stdio.h>
  8. int table[9][9];
  9. int checkrow_col();
  10. int check_block();
  11. int check();

  12. int main()
  13. {
  14.         int i, j;
  15.         while(scanf("%d", &table[0][0])==1){
  16.                 for(i=1; i!=9; ++i) scanf("%d", &table[0][i]);
  17.                 for(i=1; i!=9; ++i)
  18.                         for(j=0; j!=9; ++j) scanf("%d", &table[i][j]);
  19.                 puts( (check() ? "yes" : "no"));
  20.         }
  21.         return 0;
  22. }

  23. int check()
  24. {
  25.         if(checkrow_col()) return check_block();
  26.         return 0;
  27. }

  28. int checkrow_col()
  29. {
  30.         int i, j, cnt1, cnt2;
  31.         for(i=0; i!=9; ++i){
  32.                 for(cnt1=cnt2=j=0; j!=9; ++j)
  33.                         cnt1+=table[i][j], cnt2+=table[j][i];
  34.                 if(cnt1!=45 || cnt2!=45) return 0;
  35.         }
  36.         return 1;       
  37. }

  38. int check_block()
  39. {
  40.         int i, j, k, l, cnt;
  41.         for(i=0; i!=9; i+=3){
  42.                 for(j=0; j!=9; j+=3){
  43.                         for(k=cnt=0; k!=3; ++k)
  44.                                 for(l=0; l!=3; ++l) cnt+=table[i+k][j+l];
  45.                         if(cnt!=45) return 0;
  46.                 }
  47.         }
  48.         return 1;
  49. }
複製代碼

作者: EdisonX    時間: 2014-3-13 02:15 PM

改了一下,不用偷雞方式,這樣就沒問題了,而且速度更快。
  1. /**********************************************************************************/
  2. /*  Problem: a016 "數獨(SUDOKU)"                                                */
  3. /*  Language: C (905 Bytes)                                                       */
  4. /*  Result: AC(0ms, 280KB) judge by this@ZeroJudge                                */
  5. /*  Author: edisonx at 2014-03-13 14:14:20                                        */
  6. /**********************************************************************************/


  7. #include <stdio.h>
  8. int table[9][9];
  9. int checkrow_col();
  10. int check_block();
  11. int check();

  12. int main()
  13. {
  14.         int i, j;
  15.         while(scanf("%d", &table[0][0])==1){
  16.                 for(i=1; i!=9; ++i) scanf("%d", &table[0][i]);
  17.                 for(i=1; i!=9; ++i)
  18.                         for(j=0; j!=9; ++j) scanf("%d", &table[i][j]);
  19.                 puts( (check() ? "yes" : "no"));
  20.         }
  21.         return 0;
  22. }

  23. int check()
  24. {
  25.         if(checkrow_col()) return check_block();
  26.         return 0;
  27. }

  28. int checkrow_col()
  29. {
  30.         int i, j;
  31.         unsigned rst1=0 , rst2=0;
  32.         for(i=0; i!=9; ++i){
  33.                 for(rst1=rst2=j=0; j!=9; ++j)
  34.                         rst1|=(1U<<table[i][j]), rst2|=(1U<<table[j][i]);
  35.                 if(rst1!=0x3FE || rst2!=0x3FE) return 0;
  36.         }
  37.         return 1;        
  38. }

  39. int check_block()
  40. {
  41.         int i, j, k, l;
  42.         unsigned rst;
  43.         for(i=0; i!=9; i+=3){
  44.                 for(j=0; j!=9; j+=3){
  45.                         for(k=rst=0; k!=3; ++k)
  46.                                 for(l=0; l!=3; ++l) rst|=(1U<<table[i+k][j+l]);
  47.                         if(rst!=0x3FE) return 0;
  48.                 }
  49.         }
  50.         return 1;
  51. }
複製代碼

作者: abz53378    時間: 2014-3-16 02:02 AM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: EdisonX    時間: 2014-3-16 05:41 AM

本帖最後由 EdisonX 於 2014-3-16 05:41 AM 編輯
abz53378 發表於 2014-3-16 02:02 AM
請問一下 1U

這裡要以二進制來看。

(1) 1U << n

左移 n 個 bit,假設 n = 4 的話, 1U<<4 ,二進位得到 1 0000,翻成十進位得到 16

(2) rst | (1U<<n)

將 rst 第 n 個 bit 設成 1。

-----------

所以整體而言,rst | = (1U<<table[ i ][j] ) ;  是在判斷 table[ i ][j] 是不是剛好出現 1~9,如果 table[ i ] 裡的 1~9 都出現過的話, rst 的二進位剛好會是 11 1111 1110,這個值翻成 16 進位就是  0x3FE。用這種方式判別顯得較省力。






歡迎光臨 伊莉討論區 (http://www2.eyny.com/) Powered by Discuz!