POJ 2676 Sudoku (搜索,Dancing Links)
2014-09-02 13:23
495 查看
题目:
http://poj.org/problem?id=2676
题意:
数独,每行1-9,每列1-9,每3*3小格1-9,填数,不能重复
方法:Dancing Links(16ms)或者DFS暴搜(400-900ms)
Dancing Links(DLX) 是为了解决矩阵精确覆盖问题的算法,算法效率非常高
使用DLX解决的问题必须转化为矩阵精确覆盖问题:
1、DLX详解:
http://wenku.baidu.com/view/d8f13dc45fbfc77da269b126.html
2、转化方法:
非常详细的讲解:/article/4776920.html
约束1:每个格子只能填一个数:dlx.Link(t, encode(0, i, j));
约束2:每行需1-9:dlx.Link(t, encode(1, i, k - 1));
约束3:每列需1-9:dlx.Link(t, encode(2, j, k - 1));
约束4:每3*3格子需1-9:dlx.Link(t, encode(3, (i / 3) * 3 + j / 3, k - 1));
DLX模板(转自kuangbin(/article/4679662.html)):
POJ 2676
http://poj.org/problem?id=2676
题意:
数独,每行1-9,每列1-9,每3*3小格1-9,填数,不能重复
方法:Dancing Links(16ms)或者DFS暴搜(400-900ms)
Dancing Links(DLX) 是为了解决矩阵精确覆盖问题的算法,算法效率非常高
使用DLX解决的问题必须转化为矩阵精确覆盖问题:
1、DLX详解:
http://wenku.baidu.com/view/d8f13dc45fbfc77da269b126.html
2、转化方法:
非常详细的讲解:/article/4776920.html
约束1:每个格子只能填一个数:dlx.Link(t, encode(0, i, j));
约束2:每行需1-9:dlx.Link(t, encode(1, i, k - 1));
约束3:每列需1-9:dlx.Link(t, encode(2, j, k - 1));
约束4:每3*3格子需1-9:dlx.Link(t, encode(3, (i / 3) * 3 + j / 3, k - 1));
1 void build() 2 { 3 for (int i = 0; i < 9; i++) 4 for (int j = 0; j < 9; j++) 5 for (int k = 1; k <= 9; k++) 6 if (mtx[i][j] == '0' || mtx[i][j] == k + '0') 7 { 8 int t = encode(i, j, k - 1); 9 dlx.Link(t, encode(0, i, j)); 10 dlx.Link(t, encode(1, i, k - 1)); 11 dlx.Link(t, encode(2, j, k - 1)); 12 dlx.Link(t, encode(3, (i / 3) * 3 + j / 3, k - 1)); 13 } 14 }
DLX模板(转自kuangbin(/article/4679662.html)):
/******************************************** *ACM Solutions * *@Title: *@Version: 1.0 *@Time: 2014-xx-xx *@Solution: http://www.cnblogs.com/xysmlx/p/xxxxxxx.html * *@Author: xysmlx(Lingxiao Ma) *@Blog: http://www.cnblogs.com/xysmlx *@EMail: xysmlx@163.com * *Copyright (C) 2011-2015 xysmlx(Lingxiao Ma) ********************************************/ // #pragma comment(linker, "/STACK:102400000,102400000") #include <cstdio> #include <iostream> #include <cstring> #include <string> #include <cmath> #include <set> #include <list> #include <map> #include <iterator> #include <cstdlib> #include <vector> #include <queue> #include <stack> #include <algorithm> #include <functional> using namespace std; typedef long long LL; #define pb push_back #define ROUND(x) round(x) #define FLOOR(x) floor(x) #define CEIL(x) ceil(x) const int maxn = 0; const int maxm = 0; const int inf = 0x3f3f3f3f; const LL inf64 = 0x3f3f3f3f3f3f3f3fLL; const double INF = 1e30; const double eps = 1e-6; const int P[4] = {0, 0, -1, 1}; const int Q[4] = {1, -1, 0, 0}; const int PP[8] = { -1, -1, -1, 0, 0, 1, 1, 1}; const int QQ[8] = { -1, 0, 1, -1, 1, -1, 0, 1}; const int maxnode = 100010; const int MaxM = 1010; const int MaxN = 1010; struct DLX { int n, m, size; int U[maxnode], D[maxnode], R[maxnode], L[maxnode], Row[maxnode], Col[maxnode]; int H[MaxN], S[MaxM]; int ansd, ans[MaxN]; void init(int _n, int _m) { n = _n; m = _m; for (int i = 0; i <= m; i++) { S[i] = 0; U[i] = D[i] = i; L[i] = i - 1; R[i] = i + 1; } R[m] = 0; L[0] = m; size = m; memset(H, -1, sizeof(H)); // for (int i = 1; i <= n; i++) // H[i] = -1; } void Link(int r, int c) { ++S[Col[++size] = c]; Row[size] = r; D[size] = D[c]; U[D[c]] = size; U[size] = c; D[c] = size; if (H[r] < 0)H[r] = L[size] = R[size] = size; else { R[size] = R[H[r]]; L[R[H[r]]] = size; L[size] = H[r]; R[H[r]] = size; } } void remove(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]) { U[D[j]] = U[j]; D[U[j]] = D[j]; --S[Col[j]]; } } void resume(int c) { for (int i = U[c]; i != c; i = U[i]) for (int j = L[i]; j != i; j = L[j]) ++S[Col[U[D[j]] = D[U[j]] = j]]; L[R[c]] = R[L[c]] = c; } //d为递归深度 bool Dance(int d) { if (R[0] == 0) { ansd = d; return true; } int c = R[0]; for (int i = R[0]; i != 0; i = R[i]) if (S[i] < S[c]) c = i; remove(c); for (int i = D[c]; i != c; i = D[i]) { ans[d] = Row[i]; for (int j = R[i]; j != i; j = R[j])remove(Col[j]); if (Dance(d + 1))return true; for (int j = L[i]; j != i; j = L[j])resume(Col[j]); } resume(c); return false; } } dlx; int kase; int n, m; char mtx[20][20]; void init() { n = 9, m = 9; kase++; dlx.init(1, 324); } void input() { for (int i = 0; i < 9; i++) scanf("%s", mtx[i]); } void debug() { // } int encode(int a, int b, int c) { return a * 81 + b * 9 + c + 1; } void decode(int code, int &a, int &b, int &c) { code--; c = code % 9; code /= 9; b = code % 9; code /= 9; a = code; } void build() { for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) for (int k = 1; k <= 9; k++) if (mtx[i][j] == '0' || mtx[i][j] == k + '0') { int t = encode(i, j, k - 1); dlx.Link(t, encode(0, i, j)); dlx.Link(t, encode(1, i, k - 1)); dlx.Link(t, encode(2, j, k - 1)); dlx.Link(t, encode(3, (i / 3) * 3 + j / 3, k - 1)); } } void solve() { build(); dlx.Dance(0); for (int i = 0; i < dlx.ansd; i++) { int r, c, k; decode(dlx.ans[i], r, c, k); mtx[r][c] = k + '1'; } } void output() { for (int i = 0; i < 9; i++) printf("%s\n", mtx[i]); } int main() { // int size = 256 << 20; // 256MB // char *p = (char *)malloc(size) + size; // __asm__("movl %0, %%esp\n" :: "r"(p)); // std::ios_base::sync_with_stdio(false); #ifdef xysmlx freopen("in.cpp", "r", stdin); #endif kase = 0; int T; scanf("%d", &T); while (T--) { init(); input(); solve(); output(); } return 0; }
POJ 2676
相关文章推荐
- 简单搜索(数独)poj 2676 Sudoku
- POJ 2676 Sudoku (数独 搜索)
- POJ-2676 Sudoku 搜索
- poj2676——Sudoku(深度搜索)
- 搜索 --- 数独求解 POJ 2676 Sudoku
- 搜索 --- 数独求解 POJ 2676 Sudoku
- POJ 2676 Sudoku
- poj 2676 sudoku
- POJ-2676-Sudoku
- POJ 2676 Sudoku
- POJ 2676 Sudoku
- POJ 2676 数独(基础搜索)
- POJ 2676 Sudoku 数独游戏
- POJ 2676 SuDoKu DFS
- DFS POJ 2676 Sudoku
- POJ 2676 Sudoku 深搜
- POJ 2676-Sudoku(DFS-数独)
- POJ - 2676 Sudoku-9X9方格数独填数
- POJ - 2676 Sudoku
- POJ 2676 Sudoku (数独 DFS)