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