码迷,mamicode.com
首页 > 其他好文 > 详细

【HDOJ】3909 Sudoku

时间:2015-11-18 21:22:31      阅读:247      评论:0      收藏:0      [点我收藏+]

标签:

DLX的应用,基本题,注意maxnode开大点儿。

  1 /* 3909 */
  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 DLX {
 43     static const int maxc = 4*16*16+5;
 44     static const int maxr = 16*16*16+5;
 45     static const int maxnode = 16*16*16*5+5;
 46     
 47     int n, sz;
 48     int S[maxc];
 49     
 50     int row[maxnode], col[maxnode];
 51     int L[maxnode], R[maxnode], U[maxnode], D[maxnode];
 52     
 53     int ansd, cnt, ans[maxr], ans_[maxr];
 54     
 55     void init(int n_) {
 56         cnt = 0;
 57         n = n_;
 58         
 59         rep(i, 0, n+1) {
 60             L[i] = i-1;
 61             R[i] = i+1;
 62             U[i] = i;
 63             D[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 first = sz;
 75         int size = SZ(columns);
 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             ++cnt;
127             rep(i, 0, ansd)
128                 ans_[i] = ans[i];
129             return cnt>1;
130         }
131         
132         int c = R[0];
133         for (int i=R[0]; i!=0; i=R[i]) {
134             if (S[i] < S[c])
135                 c = i;
136         }
137         
138         remove(c);
139         for (int i=D[c]; i!=c; i=D[i]) {
140             ans[d] = row[i];
141             for (int j=R[i]; j!=i; j=R[j]) {
142                 remove(col[j]);
143             }
144             if (dfs(d + 1))    return true;
145             for (int j=L[i]; j!=i; j=L[j]) {
146                 restore(col[j]);
147             }
148         }
149         restore(c);
150         
151         return false;
152     }
153     
154     void solve(vi& v) {
155         
156         dfs(0);
157         
158         if (cnt == 1) {
159             v.clr();
160             rep(i, 0, ansd)
161                 v.pb(ans_[i]);
162         }
163     }
164     
165 } DLX;
166 
167 DLX solver;
168 int n, n2, n2n2;
169 const int maxl = 20;
170 char M[maxl][maxl], M_[maxl][maxl];
171 const int SLOT     = 0;
172 const int ROW      = 1;
173 const int COL    = 2;
174 const int SUB    = 3;
175 
176 int encode(int a, int b, int c) {
177     return a*n2n2 + b*n2 + c + 1;
178 }
179 
180 void decode(int code, int& a, int& b, int& c) {
181     --code;
182     c = code % n2;
183     code /= n2;
184     b = code % n2;
185     code /= n2;
186     a = code;
187 }
188 
189 int getVal(char c) {
190     if (c>=0 && c<=9)    return c-1;
191     return c-A+9;
192 }
193 
194 int getChar(int val) {
195     if (val < 9)    return val+1;
196     return val-9+A;
197 }
198 
199 void init() {
200     n2 = n * n;
201     n2n2 = n2 * n2;
202 }
203 
204 void solve(vi& ans) {
205     solver.init(4 * n2n2);
206         
207     rep(r, 0, n2) {
208         rep(c, 0, n2) {
209             rep(v, 0, n2) {
210                 if (M[r][c]==. || v==getVal(M[r][c])) {
211                     vi columns;
212                     columns.pb(encode(SLOT, r, c));
213                     columns.pb(encode(ROW, r, v));
214                     columns.pb(encode(COL, c, v));
215                     columns.pb(encode(SUB, r/n*n+c/n, v));
216                     solver.addRow(encode(r, c, v), columns);
217                 }
218             }
219         }
220     }
221     
222     solver.solve(ans);
223 }
224 
225 int main() {
226     ios::sync_with_stdio(false);
227     #ifndef ONLINE_JUDGE
228         freopen("data.in", "r", stdin);
229         freopen("data.out", "w", stdout);
230     #endif
231     
232     vi ans, tmp;
233     
234     while (scanf("%d", &n) != EOF) {
235         init();
236         rep(i, 0, n2)
237             scanf("%s", M[i]);        
238         
239         solve(ans);
240         
241         if (solver.cnt == 0) {
242             puts("No Solution");
243             continue;
244         } else if (solver.cnt > 1) {
245             puts("Multiple Solutions");
246             continue;
247         }
248         
249         // check if is minimal
250         bool flag = true;
251         
252         rep(r, 0, n2) {
253             rep(c, 0, n2) {
254                 if (M[r][c] != .) {
255                     char ch = M[r][c];
256                     M[r][c] = .;
257                     solve(tmp);
258                     M[r][c] = ch;
259                     if (solver.cnt <= 1) {
260                         flag = false;
261                         goto _output;
262                     }
263                 }
264             }
265         }
266         
267         _output:
268         if (flag) {        
269             int sz = SZ(ans);
270             rep(i, 0, sz) {
271                 int r, c, v;
272                 decode(ans[i], r, c, v);
273                 char ch = getChar(v);
274                 M[r][c] = ch;
275             }
276             
277             rep(i, 0, n2)
278                 puts(M[i]);
279         } else {
280             puts("Not Minimal");
281         }
282     }
283     
284     #ifndef ONLINE_JUDGE
285         printf("time = %d.\n", (int)clock());
286     #endif
287     
288     return 0;
289 }

 

【HDOJ】3909 Sudoku

标签:

原文地址:http://www.cnblogs.com/bombe1013/p/4975863.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!