POJ 3074 Sudoku DLX精确覆盖
DLX精确覆盖.....模版题
Sudoku
Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,
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 |
[Submit] [Go Back] [Status] [Discuss]
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=9; const int maxn=N*N*N+10; const int maxm=N*N*4+10; const int maxnode=maxn*4+maxm+10; char sudoku[maxn]; struct DLX { int n,m,size; int U[maxnode],D[maxnode],L[maxnode],R[maxnode],Row[maxnode],Col[maxnode]; int H[maxnode],S[maxnode]; int ansd,ans[maxn]; void init(int _n,int _m) { n=_n; m=_m; for(int i=0;i<=m;i++) { S[i]=0; U[i]=D[i]=i; L[i]=i-1; R[i]=i+1; } R[m]=0; L[0]=m; size=m; for(int i=1;i<=n;i++) H[i]=-1; } void Link(int r,int c) { ++S[Col[++size]=c]; Row[size]=r; D[size]=D[c]; U[D[c]]=size; U[size]=c; D[c]=size; if(H[r]<0) H[r]=L[size]=R[size]=size; else { R[size]=R[H[r]]; L[R[H[r]]]=size; L[size]=H[r]; R[H[r]]=size; } } 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]; --S[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]) ++S[Col[U[D[j]]=D[U[j]]=j]]; L[R[c]]=R[L[c]]=c; } bool Dance(int d) { if(R[0]==0) { for(int i=0;i<d;i++) sudoku[(ans[i]-1)/9]=(ans[i]-1)%9+'1'; printf("%s\n",sudoku); return true; } int c=R[0]; for(int i=R[0];i!=0;i=R[i]) if(S[i]<S[c]) c=i; remove(c); for(int i=D[c];i!=c;i=D[i]) { ans[d]=Row[i]; for(int j=R[i];j!=i;j=R[j]) remove(Col[j]); if(Dance(d+1)) return true; for(int j=L[i];j!=i;j=L[j]) resume(Col[j]); } resume(c); return false; } }; DLX dlx; void place(int& r,int& c1,int& c2,int& c3,int& c4,int i,int j,int k) { r=(i*N+j)*N+k; c1=i*N+j+1; c2=N*N+N*i+k; c3=N*N*2+N*j+k; c4=N*N*3+((i/3)*3+(j/3))*N+k; } int main() { while(scanf("%s",sudoku)!=EOF) { if(sudoku[2]=='d') break; dlx.init(N*N*N,N*N*4); for(int i=0;i<N;i++) { for(int j=0;j<N;j++) { for(int k=1;k<=N;k++) { if(sudoku[i*N+j]=='.'||sudoku[i*N+j]==k+'0') { int r,c1,c2,c3,c4; place(r,c1,c2,c3,c4,i,j,k); dlx.Link(r,c1); dlx.Link(r,c2); dlx.Link(r,c3); dlx.Link(r,c4); } } } } dlx.Dance(0); } return 0; }
相关文章
- POJ 3301 三分(最小覆盖正方形)
- POJ 3461 KMP
- Test for Job (poj 3249 记忆化搜索)
- POJ 1273 Drainage Ditches
- POJ 2446 Chessboard
- POJ 2239 Selecting Courses
- POJ 1459 Power Network
- 【POJ 2251】Dungeon Master(bfs)
- 【POJ 1273】Drainage Ditches(网络流)
- BZOJ 3363 POJ 1985 Cow Marathon 树的直径
- POJ 1325 && ZOJ 1364--Machine Schedule【二分图 && 最小点覆盖数】
- POJ 1182 食物链(种类并查集)
- POJ 1159 Palindrome(区间DP/最长公共子序列+滚动数组)
- poj 3041 Asteroids (最小点覆盖)
- nyoj 209 + poj 2492 A Bug's Life (并查集)