标签:
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 }
标签:
原文地址:http://www.cnblogs.com/bombe1013/p/4975863.html