POJ 3074 Sudoku (DLX)
Description
In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,
. | 2 | 7 | 3 | 8 | . | . | 1 | . |
. | 1 | . | . | . | 6 | 7 | 3 | 5 |
. | . | . | . | . | . | . | 2 | 9 |
3 | . | 5 | 6 | 9 | 2 | . | 8 | . |
. | . | . | . | . | . | . | . | . |
. | 6 | . | 1 | 7 | 4 | 5 | . | 3 |
6 | 4 | . | . | . | . | . | . | . |
9 | 5 | 1 | 8 | . | . | . | 7 | . |
. | 8 | . | . | 6 | 5 | 3 | 4 | . |
Given some of the numbers in the grid, your goal is to determine the remaining numbers such that the numbers 1 through 9 appear exactly once in (1) each of nine 3 × 3 subgrids, (2) each of the nine rows, and (3) each of the nine columns.
Input
The input test file will contain multiple cases. Each test case consists of a single line containing 81 characters, which represent the 81 squares of the Sudoku grid, given one row at a time. Each character is either a digit (from 1 to 9) or a period (used to indicate an unfilled square). You may assume that each puzzle in the input will have exactly one solution. The end-of-file is denoted by a single line containing the word “end”.
Output
For each test case, print a line representing the completed Sudoku puzzle.
Sample Input
.2738..1..1...6735.......293.5692.8...........6.1745.364.......9518...7..8..6534. ......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3. end
Sample Output
527389416819426735436751829375692184194538267268174593643217958951843672782965341 416837529982465371735129468571298643293746185864351297647913852359682714128574936
用dancing links解数独,DLX专题的终极目标,手机上的数独玩了两天后终于A了,等下把记录用这个程序刷一遍,想象下小伙伴看到我最高难度下的耗时记录的表情,啊哈哈~~
难点在于怎么建立模型,一共有9行,每行有9个数字,所以就是9 * 9,同理,列也是9 * 9,小格子也是有9个,每个也是9个数字,所以也是9 * 9,另外整个图有9 * 9 = 81的格子。所以要覆盖的列就是 9 * 9 + 9 * 9 + 9 * 9 + 81。至于行,一共有81个格子,每个格子有9种取法,所以就有81 * 9行,行和列相乘就是开的数组的大小。还有个剪枝要注意下,如果某个格子的数字已经给出,那么这一行,这一列,这一个小格子,就没必要再填这个数了,不剪枝的话会T。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <string> 5 #include <cstdlib> 6 #include <cmath> 7 #include <map> 8 #include <cctype> 9 using namespace std; 10 11 const int HEAD = 0; 12 const int SIZE = (81 * 9) * (81 * 4); 13 const int COL = 81 * 4; 14 int U[SIZE],D[SIZE],L[SIZE],R[SIZE],S[SIZE],C[SIZE],N[SIZE],P_H[SIZE],P_C[SIZE]; 15 int COUNT; 16 int TEMP[100][100]; 17 bool VIS_I[15][15],VIS_J[15][15],VIS_G[15][15]; 18 struct Node 19 { 20 int i; 21 int j; 22 int num; 23 }ANS[100]; 24 25 void ini(void); 26 void link(int,int,int,int,int,int,int); 27 bool dancing(int); 28 void remove(int); 29 void resume(int); 30 void debug(int); 31 int main(void) 32 { 33 char s[1000]; 34 while(scanf(" %s",s + 1) && strcmp(s + 1,"end")) 35 { 36 ini(); 37 for(int i = 1;i <= 9;i ++) 38 for(int j = 1;j <= 9;j ++) 39 { 40 int k = s[(i - 1) * 9 + j]; 41 int c_1,c_2,c_3,c_4; 42 if(k != '.') 43 { 44 VIS_I[i][k - '0'] = VIS_J[j][k - '0'] = true; 45 VIS_G[(i - 1) / 3 * 3 + (j - 1) / 3 + 1][k - '0'] = true; 46 c_1 = 81 * 0 + (i - 1) * 9 + k - '0'; 47 c_2 = 81 * 1 + (j - 1) * 9 + k - '0'; 48 c_3 = 81 * 2 + ((i - 1) / 3 * 3 + (j - 1) / 3) * 9 + k - '0'; 49 c_4 = 81 * 3 + (i - 1) * 9 + j; 50 link(c_1,c_2,c_3,c_4,k - '0',i,j); 51 } 52 } 53 54 for(int i = 1;i <= 9;i ++) 55 for(int j = 1;j <= 9;j ++) 56 { 57 if(s[(i - 1) * 9 + j] != '.') 58 continue; 59 int c_1,c_2,c_3,c_4; 60 for(int k = 1;k <= 9;k ++) 61 { 62 if(VIS_I[i][k] || VIS_J[j][k] || 63 VIS_G[(i - 1) / 3 * 3 + (j - 1) / 3 + 1][k]) 64 continue; 65 c_1 = 81 * 0 + (i - 1) * 9 + k; 66 c_2 = 81 * 1 + (j - 1) * 9 + k; 67 c_3 = 81 * 2 + ((i - 1) / 3 * 3 + (j - 1) / 3) * 9 + k; 68 c_4 = 81 * 3 + (i - 1) * 9 + j; 69 link(c_1,c_2,c_3,c_4,k,i,j); 70 } 71 } 72 dancing(0); 73 } 74 75 return 0; 76 } 77 78 void ini(void) 79 { 80 L[HEAD] = COL; 81 R[HEAD] = 1; 82 for(int i = 1;i <= COL;i ++) 83 { 84 L[i] = i - 1; 85 R[i] = i + 1; 86 U[i] = D[i] = C[i] = i; 87 S[i] = 0; 88 } 89 R[COL] = HEAD; 90 91 fill(&VIS_I[0][0],&VIS_I[12][12],false); 92 fill(&VIS_J[0][0],&VIS_J[12][12],false); 93 fill(&VIS_G[0][0],&VIS_G[12][12],false); 94 COUNT = COL + 1; 95 } 96 97 void link(int c_1,int c_2,int c_3,int c_4,int num,int r,int c) 98 { 99 int first = COUNT; 100 int col; 101 102 for(int i = 0;i < 4;i ++) 103 { 104 switch(i) 105 { 106 case 0:col = c_1;break; 107 case 1:col = c_2;break; 108 case 2:col = c_3;break; 109 case 3:col = c_4;break; 110 } 111 112 L[COUNT] = COUNT - 1; 113 R[COUNT] = COUNT + 1; 114 U[COUNT] = U[col]; 115 D[COUNT] = col; 116 117 D[U[col]] = COUNT; 118 U[col] = COUNT; 119 C[COUNT] = col; 120 N[COUNT] = num; 121 P_H[COUNT] = r; 122 P_C[COUNT] = c; 123 S[col] ++; 124 COUNT ++; 125 } 126 L[first] = COUNT - 1; 127 R[COUNT - 1] = first; 128 } 129 130 bool dancing(int k) 131 { 132 if(R[HEAD] == HEAD) 133 { 134 for(int i = 0;i < k;i ++) 135 TEMP[ANS[i].i][ANS[i].j] = ANS[i].num; 136 int count = 0; 137 for(int i = 1;i <= 9;i ++) 138 for(int j = 1;j <= 9;j ++) 139 printf("%d",TEMP[i][j]); 140 puts(""); 141 return true; 142 } 143 144 int c = R[HEAD]; 145 for(int i = R[HEAD];i != HEAD;i = R[i]) 146 if(S[c] > S[i]) 147 c = i; 148 149 remove(c); 150 for(int i = D[c];i != c;i = D[i]) 151 { 152 ANS[k].i = P_H[i]; 153 ANS[k].j = P_C[i]; 154 ANS[k].num = N[i]; 155 for(int j = R[i];j != i;j = R[j]) 156 remove(C[j]); 157 if(dancing(k + 1)) 158 return true; 159 for(int j = L[i];j != i;j = L[j]) 160 resume(C[j]); 161 } 162 resume(c); 163 164 return false; 165 } 166 167 void remove(int c) 168 { 169 L[R[c]] = L[c]; 170 R[L[c]] = R[c]; 171 for(int i = D[c];i != c;i = D[i]) 172 for(int j = R[i];j != i;j = R[j]) 173 { 174 D[U[j]] = D[j]; 175 U[D[j]] = U[j]; 176 S[C[j]] --; 177 } 178 } 179 180 void resume(int c) 181 { 182 L[R[c]] = c; 183 R[L[c]] = c; 184 for(int i = D[c];i != c;i = D[i]) 185 for(int j = L[i];j != i;j = L[j]) 186 { 187 D[U[j]] = j; 188 U[D[j]] = j; 189 S[C[j]] ++; 190 } 191 }