您的位置:首页 > 其它

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));

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: