【POJ】3076 Sudoku

DLX第一题,模板留念。

  1 /* 3076 */
  2 #include <iostream>
  3 #include <string>
  4 #include <map>
  5 #include <queue>
  6 #include <set>
  7 #include <stack>
  8 #include <vector>
  9 #include <deque>
 10 #include <algorithm>
 11 #include <cstdio>
 12 #include <cmath>
 13 #include <ctime>
 14 #include <cstring>
 15 #include <climits>
 16 #include <cctype>
 17 #include <cassert>
 18 #include <functional>
 19 #include <iterator>
 20 #include <iomanip>
 21 using namespace std;
 22 //#pragma comment(linker,"/STACK:102400000,1024000")
 23 
 24 #define sti                set<int>
 25 #define stpii            set<pair<int, int> >
 26 #define mpii            map<int,int>
 27 #define vi                vector<int>
 28 #define pii                pair<int,int>
 29 #define vpii            vector<pair<int,int> >
 30 #define rep(i, a, n)     for (int i=a;i<n;++i)
 31 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 32 #define clr                clear
 33 #define pb                 push_back
 34 #define mp                 make_pair
 35 #define fir                first
 36 #define sec                second
 37 #define all(x)             (x).begin(),(x).end()
 38 #define SZ(x)             ((int)(x).size())
 39 #define lson            l, mid, rt<<1
 40 #define rson            mid+1, r, rt<<1|1
 41 
 42 
 43 
 44 typedef struct DLX {
 45     static const int maxc = 4*16*16 + 5;
 46     static const int maxr = 16*16*16 + 5;
 47     static const int maxnode = 16*16*16*4 + 5;
 48     int n, sz;
 49     int S[maxc];
 50 
 51     int row[maxnode], col[maxnode];
 52     int L[maxnode], R[maxnode], U[maxnode], D[maxnode];
 53 
 54     int ansd, ans[maxr];
 55 
 56     void init(int n_)  {
 57         n = n_;
 58 
 59         for (int i=0; i<=n; ++i) {
 60             L[i] = i - 1;
 61             R[i] = i + 1;
 62             U[i] = i;
 63             D[i] = i;
 64         }
 65         L[0] = n;
 66         R[n] = 0;
 67 
 68         sz = n + 1;
 69         memset(S, 0, sizeof(S));
 70     }
 71 
 72     void addRow(int r, vi columns) {
 73         int first = sz;
 74         int size = SZ(columns);
 75 
 76         for (int i=0; i<size; ++i) {
 77             int c = columns[i];
 78 
 79             L[sz] = sz - 1;
 80             R[sz] = sz + 1;
 81 
 82             D[sz] = c;
 83             U[sz] = U[c];
 84             D[U[c]] = sz;
 85             U[c] = sz;
 86 
 87             row[sz] = r;
 88             col[sz] = c;
 89 
 90             S[c]++;
 91             sz++;
 92         }
 93 
 94         R[sz - 1] = first;
 95         L[first] = sz - 1;
 96     }
 97 
 98     void remove(int c) {
 99         L[R[c]] = L[c];
100         R[L[c]] = R[c];
101         for (int i=D[c]; i!=c; i=D[i]) {
102             for (int j=R[i]; j!=i; j=R[j]) {
103                 U[D[j]] = U[j];
104                 D[U[j]] = D[j];
105                 --S[col[j]];
106             }
107         }
108     }
109 
110     void restore(int c) {
111         for (int i=U[c]; i!=c; i=U[i]) {
112             for (int j=L[i]; j!=i; j=L[j]) {
113                 ++S[col[j]];
114                 U[D[j]] = j;
115                 D[U[j]] = j;
116             }
117         }
118         L[R[c]] = c;
119         R[L[c]] = c;
120     }
121 
122     bool dfs(int d) {
123         if (R[0] == 0) {
124             ansd = d;
125             return true;
126         }
127 
128         int c = R[0];
129         for (int i=R[0]; i!=0; i=R[i]) {
130             if (S[i] < S[c])
131                 c = i;
132         }
133 
134         remove(c);
135         for (int i=D[c]; i!=c; i=D[i]) {
136             ans[d] = row[i];
137             for (int j=R[i]; j!=i; j=R[j]) {
138                 remove(col[j]);
139             }
140             if (dfs(d+1))    return true;
141             for (int j=L[i]; j!=i; j=L[j]) {
142                 restore(col[j]);
143             }
144         }
145         restore(c);
146 
147         return false;
148     }
149 
150     bool solve(vector<int>& v) {
151         v.clr();
152 
153         if (!dfs(0))    return false;
154 
155         for (int i=0; i<ansd; ++i)
156             v.pb(ans[i]);
157 
158         return true;
159     }
160 } DLX;
161 
162 DLX solver;
163 const int SLOT = 0;
164 const int ROW = 1;
165 const int COL = 2;
166 const int SUB = 3;
167 
168 int encode(int a, int b, int c) {
169     return a*256+b*16+c+1;
170 }
171 
172 void decode(int code, int& a, int& b, int& c) {
173     --code;
174     c = code%16;
175     code /= 16;
176     b = code%16;
177     code /= 16;
178     a = code;
179 }
180 
181 char puzzle[16][20];
182 
183 bool read() {
184     rep(i, 0, 16)
185         if (scanf("%s", puzzle[i])!=1)
186             return false;
187     return true;
188 }
189 
190 int main() {
191     ios::sync_with_stdio(false);
192     #ifndef ONLINE_JUDGE
193         freopen("data.in", "r", stdin);
194         freopen("data.out", "w", stdout);
195     #endif
196 
197     int kase = 0;
198     
199     while (read()) {
200         if (kase++)
201             putchar('
');
202         
203         solver.init(1024);
204         rep(r, 0, 16) {
205             rep(c, 0, 16) {
206                 rep(v, 0, 16) {
207                     if (puzzle[r][c]=='-' || puzzle[r][c]=='A'+v) {
208                         vi columns;
209                         columns.pb(encode(SLOT, r, c));
210                         columns.pb(encode(ROW, r, v));
211                         columns.pb(encode(COL, c, v));
212                         columns.pb(encode(SUB, r/4*4+c/4, v));
213                         solver.addRow(encode(r, c, v), columns);
214                     }
215                 }
216             }
217         }
218 
219         vi ans;
220         bool flag = solver.solve(ans);
221         #ifndef ONLINE_JUDGE
222             puts(flag ? "Yes":"No");
223         #endif
224         int sz = SZ(ans);
225 
226         rep(i, 0, sz) {
227             int r, c, v;
228             decode(ans[i], r, c, v);
229             puzzle[r][c] = v + 'A';
230         }
231 
232         rep(i, 0, 16)
233             puts(puzzle[i]);
234     }
235     
236     #ifndef ONLINE_JUDGE
237         printf("time = %d.
", (int)clock());
238     #endif
239 
240     return 0;
241 }
原文地址:https://www.cnblogs.com/bombe1013/p/4974890.html