Sudoku UVALive

Sudoku

UVALive - 2659

精确覆盖问题

舞蹈链求解数独

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 const int maxn = 1025;
  5 const int maxnode = 16385;
  6 const int maxr = 4097;
  7 
  8 struct DLX{
  9     int n, sz;
 10     int S[maxn];
 11 
 12     int row[maxnode], col[maxnode];
 13     int L[maxnode], R[maxnode], U[maxnode], D[maxnode];
 14 
 15     int ansd, ans[maxr];
 16 
 17     void init(int _n){
 18         n = _n;
 19         for(int i = 0; i <= n; i++) {
 20             U[i] = i; D[i] = i; L[i] = i - 1; R[i] = i + 1;
 21         }
 22         R[n] = 0, L[0] = n;
 23 
 24         sz = n + 1;
 25         memset(S, 0, sizeof(S));
 26     }
 27 
 28     void addRow(int r, vector<int> columns){
 29         int fr = sz;
 30         for(int i = 0; i < columns.size(); i++){
 31             int c = columns[i];
 32             L[sz] = sz - 1; R[sz] = sz + 1; U[sz] = U[c]; D[sz] = c;
 33             D[U[c]] = sz; U[c] = sz;   
 34             row[sz] = r; col[sz] = c;
 35             S[c]++; sz++;
 36         }
 37         R[sz - 1] = fr; L[fr] = sz - 1;
 38     }
 39 
 40     #define FOR(i, A, s) for(int i = A[s]; i != s; i = A[i])
 41 
 42     void remove(int c){
 43         L[R[c]] = L[c];
 44         R[L[c]] = R[c];
 45         FOR(i, D, c){
 46             FOR(j, R, i){
 47                 U[D[j]] = U[j]; D[U[j]] = D[j]; --S[col[j]];
 48             }
 49         }
 50     }
 51 
 52     void restore(int c){
 53         FOR(i, U, c){
 54             FOR(j, L, i){
 55                 ++S[col[j]]; U[D[j]] = j; D[U[j]] = j;
 56             }
 57         }
 58         L[R[c]] = c;
 59         R[L[c]] = c;
 60     }
 61 
 62     bool dfs(int d){
 63         if(R[0] == 0){
 64             ansd = d;
 65             return true;
 66         }
 67         int c = R[0];
 68         FOR(i, R, 0) if(S[i] < S[c]) c = i;
 69         remove(c);
 70         FOR(i, D, c){
 71             ans[d] = row[i];
 72             FOR(j, R, i) remove(col[j]);
 73             if(dfs(d + 1)) return true;
 74             FOR(j, L, i) restore(col[j]);
 75         }  
 76         restore(c);
 77         return false;
 78     }
 79     bool solve(vector<int>& v){
 80         v.clear();
 81         if(!dfs(0)) return false;
 82         for(int i = 0; i < ansd; i++) v.push_back(ans[i]);
 83         return true;
 84     }
 85 };
 86 
 87 DLX solver;
 88 const int SLOT = 0;
 89 const int ROW = 1;
 90 const int COL = 2;
 91 const int SUB = 3;
 92 
 93 int encode(int a, int b, int c){
 94     return a * 256 +  b * 16 + c + 1;
 95 }
 96 
 97 void decode(int code, int &a, int &b, int &c){
 98     code--;
 99     c = code % 16; code /= 16;
100     b = code % 16; code /= 16;
101     a = code;
102 }
103 char puzzle[16][20];
104 
105 bool read(){
106     for(int i = 0; i < 16; i++){
107         if(scanf("%s", puzzle[i]) != 1) return false;
108     }
109     return true;
110 }
111 
112 int main(){
113     int kase = 0;
114     while(read()){
115         if(++kase != 1) puts("");
116         solver.init(1024);
117         for(int r = 0; r < 16; r++){
118             for(int c = 0; c < 16; c++){
119                 for(int v = 0; v < 16; v++){
120                     if(puzzle[r][c] == '-' || puzzle[r][c] == 'A' + v){
121                         vector<int> columns;
122                         columns.push_back(encode(SLOT, r, c));
123                         columns.push_back(encode(ROW, r, v));
124                         columns.push_back(encode(COL, c, v));
125                         columns.push_back(encode(SUB, r / 4 * 4 + c / 4, v));
126                         solver.addRow(encode(r, c, v), columns);
127                     }
128                 }
129             }
130         }
131         vector<int> ans;
132         solver.solve(ans);
133         //cout<<"

"<<ans.size()<<endl;
134         for(int i = 0; i < ans.size(); i++){
135             int r, c, v;
136             decode(ans[i], r, c, v);
137             puzzle[r][c] = 'A' + v;
138         }
139         for(int i = 0; i < 16; i++){
140             printf("%s
", puzzle[i]);
141         }
142     }
143     return 0;
144 }
View Code
原文地址:https://www.cnblogs.com/yijiull/p/8328722.html