码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 2676 Sudoku

时间:2015-04-23 23:18:15      阅读:266      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:http://poj.org/problem?id=2676

数独问题。用dancing links解决。

建图参考 http://wenku.baidu.com/link?url=3Tk5gVYew3mSQ2f2LxDODxPg3v-yqJPUaEkuZpfkHTxfSPQuM_n8TGl2Swp68XQY9MYN2BENZ-pmv9dpoh3Ulqt1lT-ZNo90jcJyi1eXasm

要注意的就是搜索的时候 要先搜索 那一列中节点最少的,否则时间会很长。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <string>
  5 #include <iomanip>
  6 using namespace std;
  7 int T;
  8 #define maxn 9*9*9*4+81*4+10
  9 int L[maxn], R[maxn], D[maxn], U[maxn];
 10 int H[maxn], C[maxn], ans[85], sum[81*4+10];
 11 int mp[10][10];
 12 int head, cnt;
 13 struct Node{
 14     int x, y, val;
 15 }hmap[9*9*9+10];
 16 void addnode(int x, int y, int val, int h){
 17     int pos1 = 81*0 + (x-1)*9+y;
 18     int pos2 = 81*1 + (x-1)*9 + val;
 19     int pos3 = 81*2 + (y-1)*9 + val;
 20     int pos4 = 81*3 + (((x-1)/3)*3 + (y-1)/3)*9 + val;
 21     
 22     H[cnt+1] = H[cnt+2] = H[cnt+3] = H[cnt+4] = h;
 23     C[cnt+1] = pos1; C[cnt+2] = pos2; C[cnt+3] = pos3; C[cnt+4] = pos4;
 24     
 25     R[cnt+1] = cnt+2; R[cnt+2] = cnt+3; R[cnt+3] = cnt+4; R[cnt+4] = cnt+1;
 26     L[cnt+1] = cnt+4; L[cnt+2] = cnt+1; L[cnt+3] = cnt+2; L[cnt+4] = cnt+3;
 27     
 28     D[U[pos1]] = cnt+1; D[cnt+1] = pos1;  U[cnt+1] = U[pos1]; U[pos1] = cnt+1;
 29     D[U[pos2]] = cnt+2; D[cnt+2] = pos2;  U[cnt+2] = U[pos2]; U[pos2] = cnt+2;
 30     D[U[pos3]] = cnt+3; D[cnt+3] = pos3;  U[cnt+3] = U[pos3]; U[pos3] = cnt+3;
 31     D[U[pos4]] = cnt+4; D[cnt+4] = pos4;  U[cnt+4] = U[pos4]; U[pos4] = cnt+4;
 32     
 33     sum[pos1]++; sum[pos2]++; sum[pos3]++; sum[pos4]++;
 34     cnt+=4;
 35     
 36     hmap[h].x = x; hmap[h].y = y; hmap[h].val = val;
 37 }
 38 void init(){
 39     memset(sum, 0, sizeof(sum));
 40     head = 0; cnt = 0;
 41     R[head] = 1; L[head] = 81*4;
 42     U[head] = head; D[head] = head;
 43     for(int i = 1; i <= 81*4; i++){  //头节点。 
 44         cnt++;
 45         H[cnt] = 0; C[cnt] = i;
 46         U[cnt] = cnt; D[cnt] = cnt;
 47         if(i == 81*4){
 48             R[cnt-1] = cnt; L[cnt] = cnt-1;
 49             R[cnt] = head;
 50         }
 51         else{
 52             R[cnt-1] = cnt; L[cnt] = cnt-1;
 53         }
 54     }
 55     int h = 0;
 56     for(int i = 1; i <= 9; i++){
 57         string temp; cin>>temp;
 58         for(int j = 0; j < 9; j++){
 59             if(temp[j] == 0){
 60                 for(int k = 1; k <= 9; k++) addnode(i, j+1, k, ++h);
 61             }
 62             else{
 63                 addnode(i, j+1, int(temp[j]-0), ++h);
 64             }
 65         }
 66     }
 67 }
 68 void remove(int c){
 69     R[L[c]] = R[c]; L[R[c]] = L[c];
 70     for(int i = D[c]; i != c; i = D[i]){
 71         for(int j = R[i]; j != i; j = R[j]){
 72             U[D[j]] = U[j]; D[U[j]] = D[j];
 73             sum[C[j]]--;
 74         }
 75     }
 76 }
 77 void resume(int c){
 78     R[L[c]] = c;
 79     L[R[c]] = c;
 80     for(int i = D[c]; i != c; i = D[i]){
 81         for(int j = R[i]; j != i; j = R[j]){
 82             U[D[j]] = j;
 83             D[U[j]] = j;
 84             sum[C[j]]++;
 85         }
 86     }
 87 }
 88 bool dance(int k){
 89     int c = R[head];
 90     if(c == head){
 91         return true;
 92     }
 93     int min = 99999;
 94     for(int i = R[head];i != head; i = R[i]){
 95         if(sum[i]<=min){
 96             min = sum[i];
 97             c = i;
 98         }
 99     }
100     remove(c);
101     for(int i = D[c]; i != c; i = D[i]){
102         ans[k] = H[i];
103         for(int j = R[i]; j != i; j = R[j]) remove(C[j]);
104         if(dance(k+1)) return true;
105         for(int j = R[i]; j != i; j = R[j]) resume(C[j]);
106     } 
107     resume(c);
108     return false;    
109 }
110 int main(){
111     scanf("%d", &T);
112     while(T--){
113         init();    
114         bool flag = dance(0);        
115         for(int i = 0; i < 81; i++){
116             mp[hmap[ans[i]].x][hmap[ans[i]].y] = hmap[ans[i]].val;
117         }
118         for(int i = 1; i <= 9; i++){
119             for(int j = 1; j <= 9; j++){
120                 printf("%d", mp[i][j]);
121             }
122             printf("\n");
123         }
124     }
125     return 0;
126 }

 

POJ 2676 Sudoku

标签:

原文地址:http://www.cnblogs.com/titicia/p/4452051.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!