SuDoKu_DLX_16*16

50Ms左右

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <ctime>
  4 #include <windows.h>
  5 const int XSIZE = 4;                                  //16*16的数独 
  6 const int _SIZE = XSIZE * XSIZE;
  7 const int MAX_SUDOKU = _SIZE * _SIZE;                    //数独矩阵大小 
  8 const int MAX_C = _SIZE * _SIZE * 4;                     //最大列 
  9 const int MAX_R = _SIZE * _SIZE * _SIZE;                 //最大行
 10 const int MAX_LINK = MAX_C * MAX_R;                      //链表最大范围
 11 
 12 int L[MAX_LINK],R[MAX_LINK],U[MAX_LINK],D[MAX_LINK];  //抽象链表
 13 int C[MAX_LINK],O[MAX_LINK],S[MAX_C],H[MAX_R];        //C&O代表列&行,S每一列的节点数,H每一行的第一个节点
 14 int NodeNumber,RecordNumber;                          //用来指向节点
 15 int ans[MAX_SUDOKU],record[MAX_R];
 16 //////////////////////Dancing Links模版//////////////////////
 17 void init(void);        //Dancing Links的抽象链表初始化 
 18 void insert(int,int);   //在链表的一个位置中添加标记 
 19 void remove(int);       //删除一列,同时删除这一列中的行 
 20 void resume(int);       //恢复一列,同时恢复这一列中的行
 21 //////////////////////Dancing Links模版//////////////////////
 22 char state[MAX_SUDOKU];
 23 bool input(void)
 24 {
 25    char buffer[_SIZE+1][_SIZE+1];   //留一个位置给'\0' 
 26    if(scanf("%s",buffer[0])==EOF)
 27       return false;
 28    for(int i=1;i<_SIZE;i++)
 29       scanf("%s",buffer[i]);
 30    for(int i=0;i<_SIZE;i++)
 31       for(int j=0;j<_SIZE;j++)
 32          {
 33             if(buffer[i][j]=='-')
 34                state[i*_SIZE+j]=0;
 35             else
 36                state[i*_SIZE+j]=buffer[i][j]-'A'+1;
 37          }
 38    return true; 
 39 }
 40 
 41 void add(int i,int j,int k)
 42 {
 43    int row=i*MAX_SUDOKU+j*_SIZE+k+1;                              //行号 
 44    insert(row,i*_SIZE + j + 1);                                       //格子有没有数字 
 45    insert(row,i*_SIZE + k + MAX_SUDOKU + 1);                            //行上有没有相同的数字 
 46    insert(row,j*_SIZE + MAX_SUDOKU * 2 + k + 1);                         //列上有没有相同的数字 
 47    insert(row,(i/XSIZE*XSIZE + j/XSIZE) * _SIZE + MAX_SUDOKU * 3 + k + 1);    //XSIZE*XSIZE的小矩阵有没有相同的数字 
 48 }
 49 
 50 void build(void)
 51 {
 52    int pos;
 53    for(int i=0;i<_SIZE;i++)
 54       for(int j=0;j<_SIZE;j++)
 55          {
 56             pos=i*_SIZE+j;
 57             if(state[pos])
 58                add(i,j,state[pos]-1);
 59             else
 60                for(int k=0;k<_SIZE;k++)
 61                   add(i,j,k);  
 62          } 
 63 }
 64 
 65 bool dfs(int k)
 66 {
 67    if(R[0]==0)
 68       {
 69          RecordNumber=k;
 70          return true;   
 71       }
 72    int count=MAX_R,c;
 73    for(int i=R[0];i;i=R[i])
 74       {
 75          if(S[i]<count)
 76             {
 77                count=S[i];
 78                c=i;
 79                if(count==1)
 80                   break;  
 81             }
 82       }
 83    remove(c);
 84    for(int i=D[c];i!=c;i=D[i])
 85       {
 86          for(int j=R[i];j!=i;j=R[j])
 87             remove(C[j]);
 88          record[k]=O[i];
 89          if(dfs(k+1))
 90             return true;
 91          for(int j=L[i];j!=i;j=L[j])
 92             resume(C[j]);
 93       }
 94    resume(c);
 95    return false;  
 96 }
 97 
 98 void output()
 99 {
100     for(int i=0;i<RecordNumber;++i)
101     {
102         ans[(record[i] - 1) / _SIZE] = ((record[i] - 1) % _SIZE) + 1;
103     }
104     for(int i=0;i<_SIZE;++i)
105     {
106         for(int j=0;j<_SIZE;++j)
107         {
108             printf("%c", ans[i * _SIZE + j] + 'A' - 1);
109         }
110         printf("\n");
111     }
112     printf("\n");
113 }
114 
115 int main()
116 {
117    while(input())
118       {
119          time_t start=clock();
120          init();
121          build();
122          dfs(0);
123          output();
124          printf("Time:%ld Ms\n",clock()-start);
125       }
126    system("pause");
127 }
128 
129 //////////////////////Dancing Links模版//////////////////////
130 void init(void)
131 {
132    for(int i=0;i<=MAX_C;i++)
133       {
134          L[i]=i-1;
135          R[i]=i+1;
136          U[i]=i;
137          D[i]=i;
138          C[i]=i;
139          O[i]=0; 
140       }
141    L[0]=MAX_C;
142    R[MAX_C]=0;
143    NodeNumber=MAX_C+1;
144    RecordNumber=0;
145    memset(S,0,sizeof(S));
146    memset(H,0,sizeof(H));
147 }
148 
149 void insert(int i,int j)   //行号,列号 
150 {
151    if(H[i])
152       {
153          L[NodeNumber]=L[H[i]];
154          R[NodeNumber]=H[i];
155          L[R[NodeNumber]]=NodeNumber;
156          R[L[NodeNumber]]=NodeNumber;
157       }
158    else
159       {
160          L[NodeNumber]=NodeNumber;
161          R[NodeNumber]=NodeNumber;
162          H[i]=NodeNumber;
163       }
164    U[NodeNumber]=U[j];
165    D[NodeNumber]=j;
166    U[D[NodeNumber]]=NodeNumber;
167    D[U[NodeNumber]]=NodeNumber;
168    C[NodeNumber]=j;
169    O[NodeNumber]=i;
170    S[j]++;
171    NodeNumber++;
172 }
173 
174 void remove(int c)
175 {
176    L[R[c]]=L[c];
177    R[L[c]]=R[c];
178    for(int i=D[c];i!=c;i=D[i])
179       {
180          for(int j=R[i];j!=i;j=R[j])
181             {
182                U[D[j]]=U[j];
183                D[U[j]]=D[j];
184                S[C[j]]--;
185             }
186       } 
187 }
188 
189 void resume(int c)
190 {
191    for(int i=U[c];i!=c;i=U[i])
192       {
193          for(int j=L[i];j!=i;j=L[j])
194             {
195                U[D[j]]=j;
196                D[U[j]]=j;
197                S[C[j]]++;
198             } 
199       }
200    L[R[c]]=c;
201    R[L[c]]=c;   
202 }
203 /*
204 --A----C-----O-I
205 -J--A-B-P-CGF-H-
206 --D--F-I-E----P-
207 -G-EL-H----M-J--
208 ----E----C--G---
209 -I--K-GA-B---E-J
210 D-GP--J-F----A--
211 -E---C-B--DP--O-
212 E--F-M--D--L-K-A
213 -C--------O-I-L-
214 H-P-C--F-A--B---
215 ---G-OD---J----H
216 K---J----H-A-P-L
217 --B--P--E--K--A-
218 -H--B--K--FI-C--
219 --F---C--D--H-N-
220 */

 

posted @ 2013-06-14 20:58  瓶哥  Views(195)  Comments(0Edit  收藏  举报