题目大意:

这是一个最简单的数独填充题目,题目保证只能产生一种数独,所以这里的初始9宫格较为稠密,可以直接dfs也没有问题

但最近练习dancing links,这类数据结构解决数独无疑效率会高很多

dancing links的数独限制条件是:

1.每行有9个元素,共9行 对应dlx81列

2.每列有9个元素,共9行 对应dlx81列

3.每个九宫格有9个元素,共9行 对应dlx81列

4.81个格子,每个格子最多有一个数

 

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <algorithm>
  5 #include <queue>
  6 #include <climits>
  7 #include <cmath>
  8 
  9 using namespace std;
 10 #define N 1000
 11 #define MAXNODE 1000000
 12 const int INF = INT_MAX;
 13 const double eps = 1e-8;
 14 
 15 int a[10][10];
 16 char str[5];
 17 
 18 int belong[9][9] =  {
 19                         {1,1,1,2,2,2,3,3,3},
 20                         {1,1,1,2,2,2,3,3,3},
 21                         {1,1,1,2,2,2,3,3,3},
 22                         {4,4,4,5,5,5,6,6,6},
 23                         {4,4,4,5,5,5,6,6,6},
 24                         {4,4,4,5,5,5,6,6,6},
 25                         {7,7,7,8,8,8,9,9,9},
 26                         {7,7,7,8,8,8,9,9,9},
 27                         {7,7,7,8,8,8,9,9,9},
 28                     };
 29 struct DLX{
 30     int n ,m , size;
 31     int col[MAXNODE] , row[MAXNODE];
 32     int U[MAXNODE] , D[MAXNODE] , L[MAXNODE] , R[MAXNODE];
 33     int cnt_col[N] , first[N];
 34     int ans[100];
 35 
 36     void init(int _n , int _m)
 37     {
 38         n = _n , m = _m;
 39         size= m ;
 40         for(int i=0 ; i<=m ; i++){
 41             L[i] = i-1 , R[i] = i+1;
 42             U[i] = D[i] = i;
 43         }
 44         L[0] = m , R[m] = 0;
 45         for(int i=1 ; i<=m ; i++) cnt_col[i] = 0;
 46         for(int i=1 ; i<=n ; i++) first[i] = -1;
 47     }
 48 
 49     void link(int r , int c)
 50     {
 51         ++size;
 52         U[D[c]] = size , D[size] = D[c];
 53         U[size] = c , D[c] = size;
 54 
 55         if(first[r]<0) L[size]=R[size]=first[r] = size;
 56         else{
 57             L[R[first[r]]] = size , R[size] = R[first[r]];
 58             L[size] = first[r] , R[first[r]] = size;
 59         }
 60         row[size] = r , col[size] = c , cnt_col[c]++;
 61     }
 62 
 63     void Remove(int c)
 64     {
 65         L[R[c]] = L[c] , R[L[c]] = R[c];
 66         for(int i=D[c] ; i!=c ; i=D[i]){
 67             for(int j=R[i] ; j!=i ; j=R[j]){
 68                 U[D[j]] = U[j] , D[U[j]] = D[j];
 69                 cnt_col[col[j]]--;
 70             }
 71         }
 72     }
 73 
 74     void Resume(int c)
 75     {
 76         for(int i=U[c] ; i!=c ; i=U[i]){
 77             for(int j=L[i] ; j!=i ; j=L[j]){
 78                 U[D[j]] = D[U[j]] = j;
 79                 cnt_col[col[j]]++;
 80             }
 81         }
 82         L[R[c]] = R[L[c]] = c;
 83     }
 84 
 85     bool Dance(int d)
 86     {
 87         if(!R[0]){
 88             for(int i=0 ; i<d ; i++){
 89                     int r = (ans[i]-1)/81;
 90                     int c = ((ans[i]-1)%81)/9;
 91                     a[r][c] = ((ans[i]-1)%9)+1;
 92             }
 93             return true;
 94         }
 95         int st=R[0];
 96         for(int i=R[0] ; i!=0 ; i=R[i])
 97             if(cnt_col[i]<cnt_col[st])
 98                 st = i;
 99         Remove(st);
100         for(int i=D[st] ; i!=st ; i=D[i]){
101             ans[d] = row[i];
102             for(int j=R[i] ; j!=i ; j=R[j]) Remove(col[j]);
103             if(Dance(d+1)) return true;
104             for(int j=L[i] ; j!=i ; j=L[j]) Resume(col[j]);
105         }
106         Resume(st);
107         return false;
108     }
109 
110 }dlx;
111 
112 void printM()
113 {
114     for(int i=0 ; i<9 ; i++)
115         for(int j=0 ; j<9 ; j++){
116            if(j<8) printf("%d " , a[i][j]);
117            else printf("%d\n" , a[i][j]);
118         }
119 }
120 
121 int main()
122 {
123   //  freopen("a.in" , "r" , stdin);
124     int index=0;
125     bool flag = false;
126     while(~scanf("%s" , str))
127     {
128         if(flag) puts("");
129         flag = true;
130         if(str[0] == '?') a[index/9][index%9] = 0;
131         else a[index/9][index%9] = str[0]-'0';
132         index++;
133         while(index<81){
134             scanf("%s" , str);
135             if(str[0] == '?') a[index/9][index%9] = 0;
136             else a[index/9][index%9] = str[0]-'0';
137             index++;
138         }
139        // printM();
140         dlx.init(729 , 324);
141         for(int i=0 ; i<9 ; i++)
142             for(int j=0 ; j<9 ; j++)
143             {
144                 if(a[i][j]){
145                     dlx.link((i*9+j)*9+a[i][j] , i*9+a[i][j]);
146                     dlx.link((i*9+j)*9+a[i][j] , 81+j*9+a[i][j]);
147                     dlx.link((i*9+j)*9+a[i][j] , 162+(belong[i][j]-1)*9+a[i][j]);
148                     dlx.link((i*9+j)*9+a[i][j] , 243+i*9+j+1);
149                 }
150                 else{
151                     for(int k=1 ; k<=9 ; k++){
152                         dlx.link((i*9+j)*9+k , i*9+k);
153                         dlx.link((i*9+j)*9+k , 81+j*9+k);
154                         dlx.link((i*9+j)*9+k , 162+(belong[i][j]-1)*9+k);
155                         dlx.link((i*9+j)*9+k , 243+i*9+j+1);
156                     }
157                 }
158             }
159         dlx.Dance(0);
160 
161         printM();
162         index=0;
163     }
164 
165     return 0;
166 }

 

 posted on 2015-05-18 23:22  Love风吟  阅读(305)  评论(0编辑  收藏  举报