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
527389416819426735436751829375692184194538267268174593643217958951843672782965341416837529982465371735129468571298643293746185864351297647913852359682714128574936
建图+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; }