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