POJ 3074 Sudoku 解题报告(Dancing Link)

Sudoku
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 7878   Accepted: 2792

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

    解题报告: Dancing Link论文上的题目,按照论文上的矩阵构造方法构造,套Dancing Link模板即可。
    对于不能确定的位置,填充0-9,对于确定的位置,仅加入该数字。可以直接在输入串上记录答案,最后输出即可。代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int M=1024*110;
const int N=1024;

int l[M], r[M], d[M], u[M], col[M], row[M], h[N], control[N];
int dcnt = 0;
char str[111];

inline void addnode(int &x)
{
	++x;
	r[x]=l[x]=u[x]=d[x]=x;
}

inline void insert_row(int rowx, int x)
{
	r[l[rowx]]=x;
	l[x]=l[rowx];
	r[x]=rowx;
	l[rowx]=x;
}

inline void insert_col(int colx, int x)
{
	d[u[colx]]=x;
	u[x]=u[colx];
	d[x]=colx;
	u[colx]=x;
}

void dlx_init(int cols)
{
	memset(h, -1, sizeof(h));
	memset(control, 0, sizeof(control));
	dcnt=-1;
	addnode(dcnt);

	for(int i=1;i<=cols;++i)
	{
		addnode(dcnt);
		insert_row(0, dcnt);
	}
}

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];
			control[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])
		{
			u[d[j]]=j;
			d[u[j]]=j;
			control[col[j]]++;
		}
		l[r[c]]=c;
		r[l[c]]=c;
}

bool DLX(int deep)
{
	if(r[0]==0)
	{
		puts(str);
		return true;
	}

	int min=M, tempc;
	for(int i=r[0];i!=0;i=r[i]) if(control[i]<min)
	{
		min=control[i];
		tempc=i;
	}
	remove(tempc);
	for(int i=d[tempc];i!=tempc;i=d[i])
	{
		str[row[i]/9]=row[i]%9+'1';
		for(int j=r[i];j!=i;j=r[j]) remove(col[j]);
		if(DLX(deep+1)) return true;
		for(int j=l[i];j!=i;j=l[j]) resume(col[j]);
	}
	resume(tempc);
	return false;
}

inline void insert_node(int x, int y)
{
	control[y]++;
	addnode(dcnt);
	row[dcnt]=x;
	col[dcnt]=y;
	insert_col(y, dcnt);
	if(h[x]==-1)
		h[x]=dcnt;
	else
		insert_row(h[x], dcnt);
}

int main()
{
#ifdef ACM
//	freopen("in.txt", "r", stdin);
#endif

	while(~scanf("%s", str) && strcmp(str, "end")!=0)
	{
		dlx_init(4*9*9);
		for(int i=1;i<=9;i++) for(int j=1;j<=9;j++)
		{
			for(int k=1;k<=9;k++) if(str[(i-1)*9+(j-1)]=='.' || str[(i-1)*9+(j-1)]=='0'+k)
			{
				int rr=(i-1)*9*9+(j-1)*9+(k-1);
				insert_node(rr, 81*0+(i-1)*9+k);
				insert_node(rr, 81*1+(j-1)*9+k);
				insert_node(rr, 81*2+((i-1)/3+(j-1)/3*3)*9+k);
				insert_node(rr, 81*3+(i-1)*9+j);
			}
		}

		DLX(0);
	}
}

你可能感兴趣的:(DancingLink)