posts - 195, comments - 34, trackbacks - 0, articles - 1

          導航

          <2009年10月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          常用鏈接

          留言簿(14)

          隨筆分類

          隨筆檔案

          文章檔案

          相冊

          收藏夾

          技術基礎

          技術相關

          研究方向

          算法類

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          目前最快的數獨求解程序 - 實現了Knuth的Dancing Links+Algorithm X算法

          //from: http://code.google.com/p/klsudoku/source/checkout
          //半瓶墨水修改于 2009 Sept 18
          //References
          //  http://en.wikipedia.org/wiki/Knuth's_Algorithm_X
          //  http://en.wikipedia.org/wiki/Dancing_Links
          //  http://en.wikipedia.org/wiki/Exact_cover#Sudoku

          #include<iostream>
          using namespace std;
          #define RR 729
          #define CC 324
          #define INF 1000000000
          int mem1[81+1];
          int mem2[81+1];
          int *mem = mem1;
          char ch[81+1];
          int cnt[CC+1];
          int scnt=0; //solution count

          struct node {
              int r,c;
              node *up;
              node *down;
              node *left;
              node *right;
          }head,all[RR*CC+99],row[RR],col[CC];int all_t;

          inline void link(int r,int c) {
              cnt[c]++;
              node *t=&all[all_t++];
              t->r=r;
              t->c=c;
              t->left=&row[r];
              t->right=row[r].right;
              t->left->right=t;
              t->right->left=t;
              t->up=&col[c];
              t->down=col[c].down;
              t->up->down=t;
              t->down->up=t;
          }

          inline void remove(int c) {
              node *t,*tt;
              col[c].right->left=col[c].left;
              col[c].left->right=col[c].right;
              for(t=col[c].down;t!=&col[c];t=t->down) {
                  for(tt=t->right;tt!=t;tt=tt->right) {
                      cnt[tt->c]--;
                      tt->up->down=tt->down;
                      tt->down->up=tt->up;
                  }
                  t->left->right=t->right;
                  t->right->left=t->left;
              }
          }

          inline void resume(int c) {
              node *t,*tt;
              for(t=col[c].down;t!=&col[c];t=t->down) {       
                  t->right->left=t;
                  t->left->right=t;
                  for(tt=t->left;tt!=t;tt=tt->left) {
                      cnt[tt->c]++;
                      tt->down->up=tt;
                      tt->up->down=tt;
                  }
              }   
              col[c].left->right=&col[c];
              col[c].right->left=&col[c];
          }

          void print_solution(int*m){
            int ans[81];
            for(int i=1;i<=81;i++) {
              int t=m[i]/9%81;
              int val=m[i]%9+1;
              ans[t]=val;
            }
            for(int i=0;i<81;i++)
              printf("%d",ans[i]);
            printf("\n");
          }

          void solve(int k)
          {
              if(head.right==&head) {//got one solution
                if (!scnt) {
                  memcpy(mem2, mem1, sizeof(mem1));
                  mem = mem2;
                }
                scnt++;
                return;
              }
              node*t,*tt;
              int min=INF,tc;
              for(t=head.right;t!=&head;t=t->right) {
                  if(cnt[t->c]<min) {
                      min=cnt[t->c];
                      tc=t->c;
                      if(min<=1)break;
                  }
              }
              remove(tc);
              for(t=col[tc].down;t!=&col[tc];t=t->down) {
                  mem[k]=t->r;
                  t->left->right=t;
                  for(tt=t->right;tt!=t;tt=tt->right) {
                      remove(tt->c);
                  }
                  t->left->right=t->right;
                  solve(k+1);
                  if (scnt >= 2)
                    return;
                  t->right->left=t;
                  for(tt=t->left;tt!=t;tt=tt->left) {
                      resume(tt->c);
                  }
                  t->right->left=t->left;
              }
              resume(tc);
              return;
          }

          int main(int argc, char**argv) {
            if (argc != 2) return 1;
            const char *p = argv[1];
            size_t len = strlen(p);
            if (len!=81) return 1;
            int i,j,k;
            for (i=0;i<81;i++) {
              if ((*p) == '0')
                ch[i] = '.';
              else
                ch[i] = *p;
              p++;
            }
            ch[81] = '\0';

            if(ch[0]=='e')return 1;
            all_t=1;
            memset(cnt,0,sizeof(cnt));
            head.left=&head;
            head.right=&head;
            head.up=&head;
            head.down=&head;
            head.r=RR;
            head.c=CC;
            for(i=0;i<CC;i++) {
              col[i].c=i;
              col[i].r=RR;
              col[i].up=&col[i];
              col[i].down=&col[i];
              col[i].left=&head;
              col[i].right=head.right;
              col[i].left->right=&col[i];
              col[i].right->left=&col[i];
            }
            for(i=0;i<RR;i++) {
              row[i].r=i;
              row[i].c=CC;
              row[i].left=&row[i];
              row[i].right=&row[i];
              row[i].up=&head;
              row[i].down=head.down;
              row[i].up->down=&row[i];
              row[i].down->up=&row[i];
            }
            for(i=0;i<RR;i++) {
              int r=i/9/9%9;
              int c=i/9%9;
              int val=i%9+1;
              if(ch[r*9+c]=='.'||ch[r*9+c]==val+'0') {
                link(i,r*9+val-1);
                link(i,81+c*9+val-1);
                int tr=r/3;
                int tc=c/3;
                link(i,162+(tr*3+tc)*9+val-1);
                link(i,243+r*9+c);
              }
            }
            for(i=0;i<RR;i++) {
              row[i].left->right=row[i].right;
              row[i].right->left=row[i].left;
            }
            solve(1);
            printf("\n");
            if (scnt>1){
              print_solution(mem1);
              print_solution(mem2);
              printf("\n2 or mroe solutions found\n");
            } else if (scnt==1) {
              print_solution(mem1);
              printf("\none solution found\n");
            } else {
              printf("\nNO solution\n");
            }
          }


          主站蜘蛛池模板: 伊春市| 靖西县| 从化市| 融水| 南召县| 柏乡县| 辉县市| 武功县| 西丰县| 宜都市| 儋州市| 万源市| 崇州市| 盈江县| 温宿县| 神池县| 阿拉善左旗| 上饶县| 彩票| 莎车县| 南阳市| 浦东新区| 江山市| 张家港市| 会宁县| 哈密市| 郸城县| 天峻县| 金阳县| 通辽市| 双桥区| 寿阳县| 崇阳县| 广宗县| 大石桥市| 海宁市| 夏邑县| 祁阳县| 华容县| 凤山县| 正阳县|