您的位置:首页 > 其它

POJ 3074 Sudoku [DLX] [SDLX]

2016-10-10 07:51 393 查看
Sudoku

Time Limit: 1000MS Memory Limit: 65536KB 64bit IO Format: %lld & %llu

Description

In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,

. 2 7 3 8 . . 1 .

. 1 . . . 6 7 3 5

. . . . . . . 2 9

3 . 5 6 9 2 . 8 .

. . . . . . . . .

. 6 . 1 7 4 5 . 3

6 4 . . . . . . .

9 5 1 8 . . . 7 .

. 8 . . 6 5 3 4 .

Given some of the numbers in the grid, your goal is to determine the remaining numbers such that the numbers 1 through 9 appear exactly once in (1) each of nine 3 × 3 subgrids, (2) each of the nine rows, and (3) each of the nine columns.

Input

The input test file will contain multiple cases. Each test case consists of a single line containing 81 characters, which represent the 81 squares of the Sudoku grid, given one row at a time. Each character is either a digit (from 1 to 9) or a period (used to indicate an unfilled square). You may assume that each puzzle in the input will have exactly one solution. The end-of-file is denoted by a single line containing the word “end”.

Output

For each test case, print a line representing the completed Sudoku puzzle.

Sample Input

.2738..1..1…6735…….293.5692.8………..6.1745.364…….9518…7..8..6534.

……52..8.4……3…9…5.1…6..2..7……..3…..6…1……….7.4…….3.

end

Sample Output

527389416819426735436751829375692184194538267268174593643217958951843672782965341

416837529982465371735129468571298643293746185864351297647913852359682714128574936

Source

Stanford Local 2006

舞蹈链解决数独问题。

转化成(9*9*9)*(4*9*9)的精确覆盖问题。

1~81列:在(i,j)有填数。

82~162列:在第i行填了数字num

163~243列:在第j列填了数字num

244~324列:在第N宫填了数字num

那么对于一个确定的格子,在原链表中加入一行,对应其四个关系。

对于一个点,在原链表中加入九行,对应其四个关系,分别是不同的数字。

这样的话,转化之后的矩阵就是答案需要覆盖的矩阵了。

可以把每一行对应的答案信息(i,j,num)储存下来。

但是会T。

优化:

IDLX , short label first

SDLX ,settled andconflict judge first

加了这两个优化之后就好可以很快出解了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
const int INF=0x3f3f3f3f;
const int maxrow = 9*9*9+5;
const int maxcol = 4*9*9+5;
const int maxn = maxrow*maxcol;
struct Node
{
int left,right,up,down;
int row,col;
}node[maxn];
#define left(x) node[x].left
#define right(x) node[x].right
#define up(x) node[x].up
#define down(x) node[x].down
#define row(x) node[x].row
#define col(x) node[x].col
int rows,cols;
int maxnode,mustselect;
int tot[maxcol];
int head;
inline void disable_row(int root)
{
left(right(root)) = left(root);
right(left(root)) = right(root);
}
inline void disable_col(int root)
{
up(down(root)) = up(root);
down(up(root)) = down(root);
}
inline void enable_row(int root)
{
left(right(root)) = root;
right(left(root)) = root;
}
inline void enable_col(int root)
{
up(down(root)) = root;
down(up(root)) = root;
}
inline void remove(int colnum)
{
disable_row(colnum);
for(int i=down(colnum);i^colnum;i=down(i))
for(int j=right(i);j^i;j=right(j))
disable_col(j),tot[col(j)]--; // needed toquery the exact current total value of the minimum column
}
inline void restore(int colnum)
{
enable_row(colnum);
for(int i=up(colnum);i^colnum;i=up(i))
for(int j=left(i);j^i;j=left(j))
enable_col(j),tot[col(j)]++;
}
inline void initialize()
{
memset(node,0,sizeof(node));
memset(tot,0,sizeof(tot));
rows=0; cols=4*9*9;
head=0;
left(head)=cols; right(head)=1;
for(int i=1;i<=cols;i++)
{
left(i) = i-1;
right(i) = i+1;
up(i) = i;
down(i) = i;
row(i) = 0;
col(i) = i;
}

4000
right(cols) = head;
maxnode=cols;
mustselect = 0;
}
struct Info
{
int x,y;
int num;
Info(const int _x = 0,const int _y = 0,const int _num = 0)
{
x=_x; y=_y; num=_num;
}
}val[maxrow];
int a[maxcol];
Info ans[maxrow];
int top;
void add_row(int a[maxcol],int cnt,Info info)
{
rows++;
val[rows] = info;
for(int i=1;i<=cnt;i++)
{
maxnode++;
tot[a[i]]++;
if(i==1)
{
left(maxnode) = maxnode;
right(maxnode) = maxnode;
}
else
{
left(maxnode) = maxnode-1;
right(maxnode) = right(maxnode-1);
enable_row(maxnode);
}
up(maxnode) = up(a[i]);
down(maxnode) = a[i];
enable_col(maxnode);
col(maxnode) = a[i];
row(maxnode) = rows;
}
}
void insert_num(int i,int j,int num)
{
int N = (i-1)/3*3 + (j-1)/3 + 1;
a[1] = (i-1)*9 + j;
a[2] = (i-1)*9 + num + 81;
a[3] = (j-1)*9 + num + 162;
a[4] = (N-1)*9 + num + 243;
add_row(a,4,Info(i,j,num));
ans[mustselect++] = val[rows];
for(int i=1;i<=4;i++) tot[a[i]]=-1,remove(a[i]);
}
void insert_dot(int i,int j)
{
int N = (i-1)/3*3 + (j-1)/3 + 1;
a[1] = (i-1)*9 + j;
a[2] = (i-1)*9 + 81;
a[3] = (j-1)*9 + 162;
a[4] = (N-1)*9 + 243;
for(int k=1;k<=9;k++)
{
a[2]++; a[3]++; a[4]++;
bool flag=true;
for(int p=1;p<=4;p++)
if(!~tot[a[p]]) flag=false;
if(flag) add_row(a,4,Info(i,j,k));
}
}
bool Dance(int k)
{
int c1 = right(head);
if(c1 == head)
{
top = k;
return true;
}
for(int i=right(c1);i^head;i=right(i))
{
if(tot[i] < tot[c1]) c1 = i;
if(!tot[i]) return false;
}
remove(c1);
for(int i=down(c1);i^c1;i=down(i))
{
ans[k] = val[row(i)];
for(int j=right(i);j^i;j=right(j)) remove(col(j));
if(Dance(k+1)) return true;
for(int j=left(i);j^i;j=left(j)) restore(col(j));
}
restore(c1);
return false;
}
int g[100][100];
void print()
{
memset(g,0,sizeof(g));
for(int i=0;i<top;i++)
{
Info tmp = ans[i];
g[tmp.x][tmp.y] = tmp.num;
}
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
putchar(g[i][j]+'0');
}
const int maxlen = 100;
char s[maxlen];
bool init()
{
scanf("%s",s);
if(s[0]=='e') return false;
initialize();
int pos=0;
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
{
if(s[pos]!='.') insert_num(i,j,s[pos]-'0');
pos++;
}
pos=0;
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
{
if(s[pos]=='.') insert_dot(i,j);
pos++;
}
return true;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("sudo.in","r",stdin);
freopen("sudo.out","w",stdout);
#endif
bool flag = true;
while(init())
{
if(!flag) putchar('\n');
flag=false;
Dance(mustselect);
print();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  DLX 搜索