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