POJ 3074 Sudoku

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

建图+dlx

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll maxn=10005;
const ll size=15;
int n,m,x,y,T,a[size][size],tot,p[1000][3];
char s[200];

inline void read(int &ret)
{
	char c;
	do { c = getchar();
	} while(c < '0' || c > '9');
	ret = c - '0';
	while((c=getchar()) >= '0' && c <= '9')
	ret = ret * 10 + ( c - '0' );
}

struct DLX
{
	int L[maxn],R[maxn],U[maxn],D[maxn];
	int row[maxn],col[maxn],ans[maxn],cnt[maxn];
	int n,m,num,sz;
	void add(int now,int l,int r,int u,int d,int x,int y)
	{
		L[now]=l;	R[now]=r;	U[now]=u;
		D[now]=d;   row[now]=x;  col[now]=y;
	}
	void reset(int n,int m)
	{
		this->n=n;	this->m=m;
		for (int i=0;i<=m;i++)
		{
			add(i,i-1,i+1,i,i,0,i);
			cnt[i]=0;
		}
		L[0]=m; 	R[m]=0; 	sz=m+1;
	}
	void insert(int x,int y)
	{
		int ft=sz-1;	
		if (row[ft]!=x)
		{
			add(sz,sz,sz,U[y],y,x,y);
			U[D[sz]]=sz; D[U[sz]]=sz;
		}
		else 
		{
			add(sz,ft,R[ft],U[y],y,x,y);
			R[L[sz]]=sz; L[R[sz]]=sz;
			U[D[sz]]=sz; D[U[sz]]=sz;
		}
		++cnt[y];	++sz;
	}
	void remove(int now)
	{
		R[L[now]]=R[now];
		L[R[now]]=L[now];
		for (int i=D[now];i!=now;i=D[i])
			for (int j=R[i];j!=i;j=R[j])
			{
				D[U[j]]=D[j];
				U[D[j]]=U[j];
				--cnt[col[j]];
			}
	}
	void resume(int now)
	{	
		for (int i=U[now];i!=now;i=U[i])
			for (int j=L[i];j!=i;j=L[j])
			{
				D[U[j]]=j;
				U[D[j]]=j;
				++cnt[col[j]];
			}
		R[L[now]]=now;
		L[R[now]]=now;
	}
	bool dfs(int x)
	{
		if (!R[0]) {num=x; return true;}
		int now=R[0];
		for (int i=now;i!=0;i=R[i])
			if (cnt[now]>cnt[i]) now=i;
		remove(now);
		for (int i=D[now];i!=now;i=D[i])
		{
			ans[x]=row[i];
			for (int j=R[i];j!=i;j=R[j]) remove(col[j]);
			if (dfs(x+1)) return true;
			for (int j=L[i];j!=i;j=L[j]) resume(col[j]);
		}
		resume(now);
		return false;
	}
	void display()
	{
		for (int i=0;i<num;++i) 
		{
			a[p[ans[i]][0]][p[ans[i]][1]]=p[ans[i]][2];
		}
		for (int i=1;i<=9;i++)
			for (int j=1;j<=9;j++) printf("%d",a[i][j]);
		puts("");
	}
}dlx;

int check(int x,int y)
{
	x=(x-1)/3;
	y=(y-1)/3;
	return 3*x+y;
}

void insert(int x,int y,int z)
{
	p[++tot][0]=x;
	p[tot][1]=y;
	p[tot][2]=z;
	dlx.insert(tot,9*(x-1)+y);
	dlx.insert(tot,81+9*(x-1)+z);
	dlx.insert(tot,162+9*(y-1)+z);
	dlx.insert(tot,243+9*check(x,y)+z);
}

int main()
{
	int c[size][size],r[size][size],u[size][size];
	while (scanf("%s",s+1),strcmp("end",s+1))
	{
		tot=0;
		memset(c,0,sizeof(c));
		memset(r,0,sizeof(r));
		memset(u,0,sizeof(u));
		dlx.reset(729,324);
		for (int i=1;i<=9;++i)
			for (int j=1;j<=9;++j) 
			{
				if (s[(i-1)*9+j]=='.') a[i][j]=0;
				else a[i][j]=s[(i-1)*9+j]-'0';
				if (a[i][j]) 
				{
					insert(i,j,a[i][j]);
					c[i][a[i][j]]=r[j][a[i][j]]=u[check(i,j)][a[i][j]]=1;
				}
			}
		for (int i=1;i<=9;++i)
			for (int j=1;j<=9;++j) 
				for (int k=1;k<=9;++k)
					if (a[i][j]+c[i][k]+r[j][k]+u[check(i,j)][k]<1) insert(i,j,k);
		if (dlx.dfs(0)) dlx.display();
	}
	return 0;
}


你可能感兴趣的:(poj)