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 */
——现在的努力是为了小时候吹过的牛B!!