poj3074 & 3076 数独 Dancing Links
2013-07-29 01:38
281 查看
今天早上又在poj看到一个数独题,粘了以前的爆搜T了,就翻出了以前写的4阶数独改了改
DancingLinks就是快
3074 三阶版
3076 4阶版
DancingLinks就是快
3074 三阶版
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <cstdlib> #include <cmath> #include <cctype> #include <queue> #include <stack> #include <utility> #include <map> #define pb push_back #define mp make_pair #define N 1025 #define M 20005 using namespace std; int U[M] , D[M] , L[M] , R[M], col[M] , row[M]; int cnt , p , s , T; char t[101]; vector<int> ans; int V(int x , int y) { return ((x / 3) * 3) + (y / 3); } #define FOR(i,A,s) for(int i = A[s]; i != s ; i = A[i]) void remove(int c) { L[R[c]] = L[c] , R[L[c]] = R[c]; FOR(i,D,c) FOR(j,R,i) U[D[j]] = U[j] , D[U[j]] = D[j] , -- s[col[j]]; } void resume(int c) { FOR(i,U,c) FOR(j,L,i) U[D[j]] = D[U[j]] = j , ++ s[col[j]]; L[R[c]] = R[L[c]] = c; } bool dfs(int d) { if (R[0] == 0) return 1; int c = R[0]; FOR(i,R,0) if (s[i] < s[c]) c = i; remove(c); FOR(i,D,c) { ans.pb(row[i]); FOR(j,R,i) remove(col[j]); if (dfs(d + 1)) return 1; FOR(j,L,i) resume(col[j]); ans.pop_back(); } resume(c); return 0; } void initmatrix() { int i , j , x , y , z , v , opt[4]; cnt = 325; for (i = 0 ; i < cnt ; ++ i) L[i] = i - 1 , R[i] = i + 1 , p[i] = i , s[i] = 0; L[0] = 324 , R[324] = 0; for (i = 0 ; i < 729 ; ++ i) { x = i / 81 , y = (i / 9) % 9 , z = i % 9; // (x , y) : A + 'z' v = V(x , y); opt[0] = 9 * x + y + 1; opt[1] = 9 * x + z + 81 + 1; opt[2] = 9 * y + z + 162 + 1; opt[3] = 9 * v + z + 243 + 1; for (j = 0 ; j < 4 ; j ++) { L[cnt + j] = cnt + j - 1 , R[cnt + j] = cnt + j + 1; D[p[opt[j]]] = cnt + j , U[cnt + j] = p[opt[j]] , p[opt[j]] = cnt + j; col[cnt + j] = opt[j] , row[cnt + j] = i , ++ s[opt[j]]; } L[cnt] = cnt + 3 , R[cnt + 3] = cnt; cnt += 4; } for (i = 0 ; i < 325 ;i ++) D[p[i]] = i , U[i] = p[i]; } bool work() { int i , j , x , y , z , v; ans.clear(); char str[12][12] = {}; if (++ T != 1) puts(""); initmatrix(); for (i = 0 ; i < 9 ; ++ i) for (j = 0 ; j < 9 ; ++ j) str[i][j] = t[i * 9 + j]; for (x = 0 ; x < 9 ; ++ x) for (y = 0 ; y < 9 ; ++ y) if (str[x][y] != '.') { z = str[x][y] - '1'; v = V(x , y); remove(9 * x + y + 1) , remove(9 * x + z + 81 + 1) , remove(9 * y + z + 162 + 1) , remove(9 * v + z + 243 + 1); } dfs(0); for (i = ans.size() - 1 ; i >= 0 ; -- i) x = ans[i] , str[x / 81][(x / 9) % 9] = '1' + (x % 9); for (i = 0 ; i < 9 ; ++ i) printf("%s",str[i]); return 0; } int main() { while(scanf("%s" , t) , *t != 'e') work(); return 0; }
3076 4阶版
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <cstdlib> #include <cmath> #include <cctype> #include <queue> #include <stack> #include <utility> #include <map> #define pb push_back #define mp make_pair #define N 1025 #define M 20005 using namespace std; int U[M] , D[M] , L[M] , R[M], col[M] , row[M]; int cnt , p , s , T; vector<int> ans; int V(int x , int y) { return ((x >> 2) << 2) + (y >> 2); } #define FOR(i,A,s) for(int i = A[s]; i != s ; i = A[i]) void remove(int c) { L[R[c]] = L[c] , R[L[c]] = R[c]; FOR(i,D,c) FOR(j,R,i) U[D[j]] = U[j] , D[U[j]] = D[j] , -- s[col[j]]; } void resume(int c) { FOR(i,U,c) FOR(j,L,i) U[D[j]] = D[U[j]] = j , ++ s[col[j]]; L[R[c]] = R[L[c]] = c; } bool dfs(int d) { if (R[0] == 0) return 1; int c = R[0]; FOR(i,R,0) if (s[i] < s[c]) c = i; remove(c); FOR(i,D,c) { ans.pb(row[i]); FOR(j,R,i) remove(col[j]); if (dfs(d + 1)) return 1; FOR(j,L,i) resume(col[j]); ans.pop_back(); } resume(c); return 0; } void initmatrix() { int i , j , x , y , z , v , opt[4]; cnt = 1025; for (i = 0 ; i < 1025 ; ++ i) L[i] = i - 1 , R[i] = i + 1 , p[i] = i , s[i] = 0; L[0] = 1024 , R[1024] = 0; for (i = 0 ; i < 4096 ; ++ i) { x = i >> 8 , y = (i >> 4) & 0xf , z = i & 0xf; // (x , y) : A + 'z' v = V(x , y); opt[0] = 16 * x + y + 1; opt[1] = 16 * x + z + 256 + 1; opt[2] = 16 * y + z + 512 + 1; opt[3] = 16 * v + z + 768 + 1; for (j = 0 ; j < 4 ; j ++) { L[cnt + j] = cnt + j - 1 , R[cnt + j] = cnt + j + 1; D[p[opt[j]]] = cnt + j , U[cnt + j] = p[opt[j]] , p[opt[j]] = cnt + j; col[cnt + j] = opt[j] , row[cnt + j] = i , ++ s[opt[j]]; } L[cnt] = cnt + 3 , R[cnt + 3] = cnt; cnt += 4; } for (i = 0 ; i < 1025 ;i ++) D[p[i]] = i , U[i] = p[i]; } bool work() { int i , j , x , y , z , v; ans.clear(); char str[16][20]; if (!~scanf("%s\n",str[0])) return 1; if (++ T != 1) puts(""); initmatrix(); for (i = 1 ; i < 16 ; ++ i) scanf("%s\n",str[i]); for (x = 0 ; x < 16 ; ++ x) for (y = 0 ; y < 16 ; ++ y) if (str[x][y] != '-') { z = str[x][y] - 'A'; v = V(x , y); remove(16 * x + y + 1) , remove(16 * x + z + 256 + 1) , remove(16 * y + z + 512 + 1) , remove(16 * v + z + 768 + 1); } dfs(0); for (i = ans.size() - 1 ; i >= 0 ; -- i) x = ans[i] , str[x >> 8][(x >> 4) & 0xf] = 'A' + (x & 0xf); for (i = 0 ; i < 16 ; ++ i) printf("%s\n",str[i]); return 0; } int main() { while(1) if(work()) break; return 0; }
相关文章推荐
- poj 3074/3076 数独(Dancing Links)
- poj3074 poj3076 数独问题 dancing links
- POJ 3076 16×16数独
- I'm going to dance 数独问题 poj 3076
- poj 3076 Sudoku(Dancing Links)
- 英特尔® 线程挑战赛—数独
- poj3074 9*9数独,poj3076 16*16数独 DLX
- tju 3219& hdu2295(Dancing Links重复覆盖模板题)
- zoj 3122(数独 Dancing Links精确覆盖)
- Poj3074-Sudoku(数独DLX)
- POJ 2676 && POJ 2918 数独 DFS
- CDOJ 1222--Sudoku【DFS && 数独】
- POJ 3076 Sudoku 数独模板
- 转载 - 算法实践——舞蹈链(Dancing Links)算法求解数独
- CWINDOWSsystem32 1025, 1028, 1031, 1033, 1037, 1041, 1053, 2052 & 3076
- POJ 2676 数独 && 编程之美1.15
- "数独高手"C++源码
- dancing links 算法学习小记 Poj 3074 Sudoku (数独)
- Sudoku 数独 (Dancing links)
- 算法实践——舞蹈链(Dancing Links)算法求解数独