UVa 1309 DLX Sudoku
16×16的数独。
看白书学的DLX,有些细节还有待消化,贴个模板先。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <vector> 5 #include <queue> 6 using namespace std; 7 8 const int maxn = 16; 9 const int maxnode = 16384 + 100; 10 const int maxr = 4096 + 10; 11 const int maxc = 1024 + 10; 12 13 #define FOR(i,A,s) for(int i = A[s]; i != s; i = A[i]) 14 15 struct DLX 16 { 17 int n, sz; 18 int S[maxc]; 19 20 int row[maxnode], col[maxnode]; 21 int L[maxnode], R[maxnode], U[maxnode], D[maxnode]; 22 23 int ansd, ans[maxr]; 24 25 void init(int n) 26 { 27 this-> n = n; 28 29 for(int i = 0; i <= n; i++) { 30 U[i] = D[i] = i; L[i] = i - 1; R[i] = i + 1; 31 } 32 L[0] = n; R[n] = 0; 33 34 sz = n + 1; 35 memset(S, 0, sizeof(S)); 36 } 37 38 void AddRow(int r, vector<int> columns) 39 { 40 int first = sz; 41 for(int i = 0; i < columns.size(); i++) 42 { 43 int c = columns[i]; 44 L[sz] = sz - 1; R[sz] = sz + 1; D[sz] = c; U[sz] = U[c]; 45 D[U[c]] = sz; U[c] = sz; 46 row[sz] = r; col[sz] = c; 47 S[c]++; sz++; 48 } 49 R[sz - 1] = first; L[first] = sz - 1; 50 } 51 52 void remove(int c) 53 { 54 L[R[c]] = L[c]; 55 R[L[c]] = R[c]; 56 FOR(i,D,c) 57 FOR(j,R,i) { U[D[j]] = U[j]; D[U[j]] = D[j]; --S[col[j]]; } 58 } 59 60 void restore(int c) 61 { 62 FOR(i,U,c) 63 FOR(j,L,i) { ++S[col[j]]; U[D[j]] = j; D[U[j]] = j; } 64 L[R[c]] = c; 65 R[L[c]] = c; 66 } 67 68 bool dfs(int d) 69 { 70 if(R[0] == 0) { ansd = d; return true; } 71 72 int c = R[0]; 73 FOR(i,R,0) if(S[i] < S[c]) c = i; 74 75 remove(c); 76 FOR(i,D,c) 77 { 78 ans[d] = row[i]; 79 FOR(j,R,i) remove(col[j]); 80 if(dfs(d + 1)) return true; 81 FOR(j,L,i) restore(col[j]); 82 } 83 restore(c); 84 85 return false; 86 } 87 88 bool solve(vector<int>& v) 89 { 90 v.clear(); 91 if(!dfs(0)) return false; 92 for(int i = 0; i < ansd; i++) v.push_back(ans[i]); 93 return true; 94 } 95 }solver; 96 97 const int SLOT = 0; 98 const int ROW = 1; 99 const int COL = 2; 100 const int SUB = 3; 101 102 int encode(int a, int b, int c) { 103 return a * 256 + b * 16 + c + 1; 104 } 105 106 void decode(int code, int& a, int& b, int& c) { 107 code--; 108 c = code % 16; code /= 16; 109 b = code % 16; code /= 16; 110 a = code % 16; 111 } 112 113 char G[maxn][maxn + 10]; 114 115 bool read() 116 { 117 for(int i = 0; i < 16; i++) 118 if(scanf("%s", G[i]) != 1) return false; 119 return true; 120 } 121 122 int main() 123 { 124 int kase = 0; 125 while(read()) 126 { 127 if(kase++ > 0) puts(""); 128 129 solver.init(1024); 130 for(int r = 0; r < 16; r++) 131 for(int c = 0; c < 16; c++) 132 for(int v = 0; v < 16; v++) 133 if(G[r][c] == '-' || G[r][c] == 'A' + v) { 134 vector<int> columns; 135 //一行完成四个任务 136 columns.push_back(encode(SLOT, r, c)); 137 columns.push_back(encode(ROW, r, v)); 138 columns.push_back(encode(COL, c, v)); 139 columns.push_back(encode(SUB, (r/4)*4+c/4, v)); 140 solver.AddRow(encode(r,c,v), columns); 141 } 142 143 vector<int> ans; 144 solver.solve(ans); 145 146 for(int i = 0; i < ans.size(); i++) { 147 int r, c, v; 148 decode(ans[i], r, c, v); 149 G[r][c] = 'A' + v; 150 } 151 152 for(int i = 0; i < 16; i++) printf("%s\n", G[i]); 153 } 154 155 return 0; 156 }