POJ 2676 Sudoku 跳舞链 || dfs
2017-08-13 21:11
246 查看
题目:
http://poj.org/problem?id=2676题意:
数独。。。思路:
跳舞链水过,用dfs也可以过跳舞链(15ms):
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int X = 100000 + 10, N = 800 + 10, M = 400 + 10, INF = 0x3f3f3f3f; struct DLX { int U[X], D[X], L[X], R[X], row[X], col[X]; int H , S[M]; int head, sz, tot, n, m, ans ; void init(int _n, int _m) { n = _n, m = _m; for(int i = 0; i <= m; i++) L[i] = i-1, R[i] = i+1, U[i] = D[i] = i, S[i] = 0; head = 0, tot = 0, sz = m; L[head] = m, R[m] = head; for(int i = 1; i <= n; i++) H[i] = -1; } void link(int r, int c) { ++S[col[++sz]=c]; row[sz] = r; D[sz] = D[c], U[D[c]] = sz; U[sz] = c, D[c] = sz; if(H[r] < 0) H[r] = L[sz] = R[sz] = sz; else R[sz] = R[H[r]], L[R[H[r]]] = sz, L[sz] = H[r], R[H[r]] = sz; } void del(int c) { L[R[c]] = L[c], R[L[c]] = R[c]; for(int i = D[c]; i != c; i = D[i]) for(int j = R[i]; j != i; j = R[j]) D[U[j]] = D[j], U[D[j]] = U[j], --S[col[j]]; } void recover(int c) { for(int i = U[c]; i != c; i = U[i]) for(int j = L[i]; j != i; j = L[j]) D[U[j]] = U[D[j]] = j, ++S[col[j]]; R[L[c]] = L[R[c]] = c; } bool dance(int dep) { if(R[head] == head) { tot = dep-1; return true; } int c = R[head]; for(int i = R[head]; i != head; i = R[i]) if(S[i] < S[c]) c = i; del(c); for(int i = D[c]; i != c; i = D[i]) { ans[dep] = row[i]; for(int j = R[i]; j != i; j = R[j]) del(col[j]); if(dance(dep + 1)) return true; for(int j = L[i]; j != i; j = L[j]) recover(col[j]); } recover(c); return false; } }dlx; void calc(int x, int y, int k, int len) { int r = ((x-1) * len + (y-1)) * len + k; dlx.link(r, (x-1) * len + k); dlx.link(r, len*len + (y-1) * len + k); int base = sqrt(1.0 * len); int block = (x-1) / base * base + (y-1) / base + 1; dlx.link(r, len*len*2 + (block-1) * len + k); dlx.link(r, len*len*3 + (x-1) * len + y); } void print(int len) { sort(dlx.ans + 1, dlx.ans + 1 + dlx.tot); for(int i = 1; i <= len; i++) { for(int j = 1; j <= len; j++) printf("%d", dlx.ans[(i-1)*len+j] - ((i-1)*len + (j-1)) * len); printf("\n"); } } int main() { int t, len = 9; scanf("%d", &t); while(t--) { char ch; dlx.init(len * len * len, len * len * 4); for(int i = 1; i <= len; i++) for(int j = 1; j <= len; j++) { scanf(" %c", &ch); if(ch == '0') for(int k = 1; k <= len; k++) calc(i, j, k, len); else calc(i, j, ch-'0', len); } dlx.dance(1); print(len); } return 0; }
dfs(422ms):
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 10; char s ; bool row , col , block ; bool found; void dfs(int i, int j) { if(i == 9 && j == 0) { found = true; for(int i = 0; i < 9; i++) printf("%s\n", s[i]); } if(s[i][j] == '0') for(int k = 1; k <= 9; k++) { if(!row[i][k] && !col[j][k] && !block[i/3*3+j/3+1][k]) { s[i][j] = k + '0'; row[i][k] = true; col[j][k] = true; block[i/3*3+j/3+1][k] = true; if(j != 8) dfs(i, j + 1); else dfs(i + 1, 0); if(found) return; s[i][j] = '0'; row[i][k] = false; col[j][k] = false; block[i/3*3+j/3+1][k] = false; } } else { if(j != 8) dfs(i, j + 1); else dfs(i + 1, 0); } } int main() { int t; scanf("%d", &t); while(t--) { memset(row, 0, sizeof row); memset(col, 0, sizeof col); memset(block, 0, sizeof block); for(int i = 0; i < 9; i++) scanf("%s", s[i]); for(int i = 0; i < 9; i++) for(int j = 0; j < 9; j++) { row[i][s[i][j]-'0'] = true; col[j][s[i][j]-'0'] = true; block[i/3*3+j/3+1][s[i][j]-'0'] = true; } found = false; dfs(0, 0); } return 0; }
相关文章推荐
- POJ 2676 Sudoku (DFS)
- POJ 2676 Sudoku (数独求解器 DFS)
- Poj 2676 Sudoku[dfs]
- POJ 2676 Sudoku (数独 DFS)
- poj_2676 Sudoku(dfs)
- poj 2676 sudoku dfs
- POJ 2676-Sudoku(DFS)
- POJ 2676 sudoku dfs
- poj 2676 sudoku ( 数独)----DFS
- POJ 2676 Sudoku 【dfs】
- POJ-2676 Sudoku(DFS)
- POJ-2676 Sudoku (DFS)
- POJ-2676-Sudoku-DFS
- poj 2676 sudoku(DFS)
- POJ 2676 Sudoku(经典DFS)
- POJ 2676 Sudoku (DFS回溯剪枝)
- [DFS]poj 2676 Sudoku 数独问题
- POJ 2676 Sudoku (数独 DFS)
- DFS POJ 2676 Sudoku
- POJ 2676 Sudoku1 (DFS)