【HDOJ】4210 Su-domino-ku

DLX。在模板的基础上增加一个FILL属性,略修改即可。

  1 /* 4210 */
  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 typedef struct {
 43     static const int maxc = 5*9*9+5;
 44     static const int maxr = 13205;
 45     static const int maxn = maxr * maxc;
 46     
 47     int n, sz;
 48     int S[maxc];
 49     
 50     int row[maxn], col[maxn];
 51     int L[maxn], R[maxn], U[maxn], D[maxn];
 52     
 53     int ansd, ans[maxr];
 54     
 55     void init(int n_) {
 56         n = n_;
 57         
 58         rep(i, 0, n+1) {
 59             L[i] = i - 1;
 60             R[i] = i + 1;
 61             U[i] = i;
 62             D[i] = i;
 63             col[i] = i;
 64         }
 65         
 66         L[0] = n;
 67         R[n] = 0;
 68         
 69         sz = n + 1;
 70         memset(S, 0, sizeof(S));
 71     }
 72     
 73     void addRow(int r, vi columns) {
 74         int size = SZ(columns);
 75         int first = sz;
 76         
 77         rep(i, 0, size) {
 78             int c = columns[i];
 79             
 80             L[sz] = sz - 1;
 81             R[sz] = sz + 1;
 82             
 83             D[sz] = c;
 84             U[sz] = U[c];
 85             D[U[c]] = sz;
 86             U[c] = sz;
 87             
 88             row[sz] = r;
 89             col[sz] = c;
 90             
 91             ++S[c];
 92             ++sz;
 93         }
 94         
 95         R[sz-1] = first;
 96         L[first] = sz-1;
 97     }
 98     
 99     void remove(int c) {
100         L[R[c]] = L[c];
101         R[L[c]] = R[c];
102         for (int i=D[c]; i!=c; i=D[i]) {
103             for (int j=R[i]; j!=i; j=R[j]) {
104                 U[D[j]] = U[j];
105                 D[U[j]] = D[j];
106                 --S[col[j]];
107             }
108         }
109     }
110     
111     void restore(int c) {
112         L[R[c]] = c;
113         R[L[c]] = c;
114         for (int i=D[c]; i!=c; i=D[i]) {
115             for (int j=R[i]; j!=i; j=R[j]) {
116                 U[D[j]] = j;
117                 D[U[j]] = j;
118                 ++S[col[j]];
119             }
120         }
121     }
122     
123     bool dfs(int d) {
124         if (R[0] == 0) {
125             ansd = d;
126             return true;
127         }
128         
129         int c = R[0];
130         for (int i=R[0]; i!=0; i=R[i]) {
131             if (S[i] < S[c])
132                 c = i;
133         }
134         
135         remove(c);
136         for (int i=D[c]; i!=c; i=D[i]) {
137             ans[d] = row[i];
138             for (int j=R[i]; j!=i; j=R[j]) {
139                 remove(col[j]);
140             }
141             if(dfs(d + 1))    return true;
142             for (int j=L[i]; j!=i; j=L[j]) {
143                 restore(col[j]);
144             }
145         }
146         restore(c);
147         
148         return false; 
149     }
150     
151     void solve(vi& v) {
152         v.clr();
153         
154         dfs(0);
155         
156         rep(i, 0, ansd)
157             v.pb(ans[i]);
158     }
159     
160 } DLX;
161 
162 typedef struct {
163     int a, b;
164     int r, c;
165     int d;
166 } node_t;
167 
168 const int SLOT = 0;
169 const int ROW = 1;
170 const int COL = 2;
171 const int SUB = 3;
172 const int FILL = 4;
173 const int maxn = 13205;
174 int M[10][10];
175 bool mark[10][10];
176 DLX solver;
177 node_t nd[maxn];
178 int rn;
179 vi ans;
180 
181 int encode(int a, int b, int c) {
182     return a*81 + b*9 + c+1;
183 }
184 
185 void decode(int code, int& a, int& b, int& c) {
186     --code;
187     c = code % 9;
188     code /= 9;
189     b = code % 9;
190     code /= 9;
191     a = code;
192 }
193 
194 void init() {
195     rn = 1;
196     memset(mark, false, sizeof(mark));
197 }
198 
199 void input(int n) {
200     int r, c;
201     int x1, x2;
202     char ps1[5], ps2[5], ps[5];
203     
204     solver.init(5*9*9);
205     init();
206     rep(i, 0, n) {
207         scanf("%d %s %d %s", &x1, ps1, &x2, ps2);
208         vi columns;
209         
210         // handle 1-st
211         r = ps1[0]-'A';
212         c = ps1[1]-'1';
213         --x1;
214         columns.pb(encode(SLOT, r, c));
215         columns.pb(encode(ROW, r, x1));
216         columns.pb(encode(COL, c, x1));
217         columns.pb(encode(SUB, r/3*3+c/3, x1));
218         M[r][c] = x1;
219         
220         // handle 2-nd
221         r = ps2[0]-'A';
222         c = ps2[1]-'1';
223         --x2;
224         columns.pb(encode(SLOT, r, c));
225         columns.pb(encode(ROW, r, x2));
226         columns.pb(encode(COL, c, x2));
227         columns.pb(encode(SUB, r/3*3+c/3, x2));
228         M[r][c] = x2;
229         
230         mark[x1][x2] = mark[x2][x1] = true;
231         columns.pb(encode(FILL, x1, x2));
232         columns.pb(encode(FILL, x2, x1));
233         solver.addRow(rn++, columns);
234     }
235     rep(i, 0, 9) {
236         scanf("%s", ps);
237         r = ps[0]-'A';
238         c = ps[1]-'1';
239         M[r][c] = i;
240         mark[i][i] = true;
241         vi columns;
242         columns.pb(encode(SLOT, r, c));
243         columns.pb(encode(ROW, r, i));
244         columns.pb(encode(COL, c, i));
245         columns.pb(encode(SUB, r/3*3+c/3, i));
246         columns.pb(encode(FILL, i, i));
247         solver.addRow(rn++, columns);
248     }
249     rep(i, 0, 9) {
250         rep(j, 0, 9) {
251             if (mark[i][j])
252                 continue;
253             for (r=0; r<=8; ++r) {
254                 for (c=0; c<8; ++c) {
255                     nd[rn].a = i;
256                     nd[rn].b = j;
257                     nd[rn].d = 0;
258                     nd[rn].r = r;
259                     nd[rn].c = c;
260                     
261                     vi columns;
262                     columns.pb(encode(SLOT, r, c));
263                     columns.pb(encode(ROW, r, i));
264                     columns.pb(encode(COL, c, i));
265                     columns.pb(encode(SUB, r/3*3+c/3, i));
266                     int cc = c + 1;
267                     columns.pb(encode(SLOT, r, cc));
268                     columns.pb(encode(ROW, r, j));
269                     columns.pb(encode(COL, cc, j));
270                     columns.pb(encode(SUB, r/3*3+cc/3, j));
271                     columns.pb(encode(FILL, i, j));
272                     columns.pb(encode(FILL, j, i));
273                     solver.addRow(rn++, columns);
274                 }
275             }
276             
277             for(r=0; r<8; ++r) {
278                 int rr = r + 1;
279                 for (c=0; c<=8; ++c) {
280                     nd[rn].a = i;
281                     nd[rn].b = j;
282                     nd[rn].d = 1;
283                     nd[rn].r = r;
284                     nd[rn].c = c;
285                     
286                     vi columns;
287                     columns.pb(encode(SLOT, r, c));
288                     columns.pb(encode(ROW, r, i));
289                     columns.pb(encode(COL, c, i));
290                     columns.pb(encode(SUB, r/3*3+c/3, i));
291                     columns.pb(encode(SLOT, rr, c));
292                     columns.pb(encode(ROW, rr, j));
293                     columns.pb(encode(COL, c, j));
294                     columns.pb(encode(SUB, rr/3*3+c/3, j));
295                     columns.pb(encode(FILL, i, j));
296                     columns.pb(encode(FILL, j, i));
297                     solver.addRow(rn++, columns);
298                 }
299             }
300         }
301     }
302 }
303 
304 void solve(int n) {
305     solver.solve(ans);
306     int sz = SZ(ans), id;
307     n += 9;
308     
309     rep(i, 0, sz) {
310         if (ans[i] > n) {
311             id = ans[i];
312             if (nd[id].d) {
313                 M[nd[id].r][nd[id].c] = nd[id].a;
314                 M[nd[id].r+1][nd[id].c] = nd[id].b;
315             } else {
316                 M[nd[id].r][nd[id].c] = nd[id].a;
317                 M[nd[id].r][nd[id].c+1] = nd[id].b;
318             }
319         }
320     }
321     
322     rep(i, 0, 9) {
323         rep(j, 0, 9) {
324             ++M[i][j];
325             printf("%d", M[i][j]);
326         }
327         putchar('
');
328     }
329 }
330 
331 int main() {
332     ios::sync_with_stdio(false);
333     #ifndef ONLINE_JUDGE
334         freopen("data.in", "r", stdin);
335         freopen("data.out", "w", stdout);
336     #endif
337     
338     int n;
339     int t = 0;
340     
341     while (scanf("%d",&n)!=EOF && n) {
342         memset(mark, false, sizeof(mark));
343         input(n);
344         printf("Puzzle %d
", ++t);
345         solve(n);
346     }
347     
348     #ifndef ONLINE_JUDGE
349         printf("time = %d.
", (int)clock());
350     #endif
351     
352     return 0;
353 }
原文地址:https://www.cnblogs.com/bombe1013/p/5062950.html