POJ 3074 Sudoku [DLX] [SDLX]
2016-10-10 07:51
393 查看
Sudoku
Time Limit: 1000MS Memory Limit: 65536KB 64bit IO Format: %lld & %llu
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
Stanford Local 2006
舞蹈链解决数独问题。
转化成(9*9*9)*(4*9*9)的精确覆盖问题。
1~81列:在(i,j)有填数。
82~162列:在第i行填了数字num
163~243列:在第j列填了数字num
244~324列:在第N宫填了数字num
那么对于一个确定的格子,在原链表中加入一行,对应其四个关系。
对于一个点,在原链表中加入九行,对应其四个关系,分别是不同的数字。
这样的话,转化之后的矩阵就是答案需要覆盖的矩阵了。
可以把每一行对应的答案信息(i,j,num)储存下来。
但是会T。
优化:
IDLX , short label first
SDLX ,settled andconflict judge first
加了这两个优化之后就好可以很快出解了。
Time Limit: 1000MS Memory Limit: 65536KB 64bit IO Format: %lld & %llu
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
Stanford Local 2006
舞蹈链解决数独问题。
转化成(9*9*9)*(4*9*9)的精确覆盖问题。
1~81列:在(i,j)有填数。
82~162列:在第i行填了数字num
163~243列:在第j列填了数字num
244~324列:在第N宫填了数字num
那么对于一个确定的格子,在原链表中加入一行,对应其四个关系。
对于一个点,在原链表中加入九行,对应其四个关系,分别是不同的数字。
这样的话,转化之后的矩阵就是答案需要覆盖的矩阵了。
可以把每一行对应的答案信息(i,j,num)储存下来。
但是会T。
优化:
IDLX , short label first
SDLX ,settled andconflict judge first
加了这两个优化之后就好可以很快出解了。
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<vector> #include<queue> #include<stack> #include<map> #include<set> #include<string> #include<iomanip> #include<ctime> #include<climits> #include<cctype> #include<algorithm> #ifdef WIN32 #define AUTO "%I64d" #else #define AUTO "%lld" #endif using namespace std; #define smax(x,tmp) x=max((x),(tmp)) #define smin(x,tmp) x=min((x),(tmp)) #define maxx(x1,x2,x3) max(max(x1,x2),x3) #define minn(x1,x2,x3) min(min(x1,x2),x3) const int INF=0x3f3f3f3f; const int maxrow = 9*9*9+5; const int maxcol = 4*9*9+5; const int maxn = maxrow*maxcol; struct Node { int left,right,up,down; int row,col; }node[maxn]; #define left(x) node[x].left #define right(x) node[x].right #define up(x) node[x].up #define down(x) node[x].down #define row(x) node[x].row #define col(x) node[x].col int rows,cols; int maxnode,mustselect; int tot[maxcol]; int head; inline void disable_row(int root) { left(right(root)) = left(root); right(left(root)) = right(root); } inline void disable_col(int root) { up(down(root)) = up(root); down(up(root)) = down(root); } inline void enable_row(int root) { left(right(root)) = root; right(left(root)) = root; } inline void enable_col(int root) { up(down(root)) = root; down(up(root)) = root; } inline void remove(int colnum) { disable_row(colnum); for(int i=down(colnum);i^colnum;i=down(i)) for(int j=right(i);j^i;j=right(j)) disable_col(j),tot[col(j)]--; // needed toquery the exact current total value of the minimum column } inline void restore(int colnum) { enable_row(colnum); for(int i=up(colnum);i^colnum;i=up(i)) for(int j=left(i);j^i;j=left(j)) enable_col(j),tot[col(j)]++; } inline void initialize() { memset(node,0,sizeof(node)); memset(tot,0,sizeof(tot)); rows=0; cols=4*9*9; head=0; left(head)=cols; right(head)=1; for(int i=1;i<=cols;i++) { left(i) = i-1; right(i) = i+1; up(i) = i; down(i) = i; row(i) = 0; col(i) = i; } 4000 right(cols) = head; maxnode=cols; mustselect = 0; } struct Info { int x,y; int num; Info(const int _x = 0,const int _y = 0,const int _num = 0) { x=_x; y=_y; num=_num; } }val[maxrow]; int a[maxcol]; Info ans[maxrow]; int top; void add_row(int a[maxcol],int cnt,Info info) { rows++; val[rows] = info; for(int i=1;i<=cnt;i++) { maxnode++; tot[a[i]]++; if(i==1) { left(maxnode) = maxnode; right(maxnode) = maxnode; } else { left(maxnode) = maxnode-1; right(maxnode) = right(maxnode-1); enable_row(maxnode); } up(maxnode) = up(a[i]); down(maxnode) = a[i]; enable_col(maxnode); col(maxnode) = a[i]; row(maxnode) = rows; } } void insert_num(int i,int j,int num) { int N = (i-1)/3*3 + (j-1)/3 + 1; a[1] = (i-1)*9 + j; a[2] = (i-1)*9 + num + 81; a[3] = (j-1)*9 + num + 162; a[4] = (N-1)*9 + num + 243; add_row(a,4,Info(i,j,num)); ans[mustselect++] = val[rows]; for(int i=1;i<=4;i++) tot[a[i]]=-1,remove(a[i]); } void insert_dot(int i,int j) { int N = (i-1)/3*3 + (j-1)/3 + 1; a[1] = (i-1)*9 + j; a[2] = (i-1)*9 + 81; a[3] = (j-1)*9 + 162; a[4] = (N-1)*9 + 243; for(int k=1;k<=9;k++) { a[2]++; a[3]++; a[4]++; bool flag=true; for(int p=1;p<=4;p++) if(!~tot[a[p]]) flag=false; if(flag) add_row(a,4,Info(i,j,k)); } } bool Dance(int k) { int c1 = right(head); if(c1 == head) { top = k; return true; } for(int i=right(c1);i^head;i=right(i)) { if(tot[i] < tot[c1]) c1 = i; if(!tot[i]) return false; } remove(c1); for(int i=down(c1);i^c1;i=down(i)) { ans[k] = val[row(i)]; for(int j=right(i);j^i;j=right(j)) remove(col(j)); if(Dance(k+1)) return true; for(int j=left(i);j^i;j=left(j)) restore(col(j)); } restore(c1); return false; } int g[100][100]; void print() { memset(g,0,sizeof(g)); for(int i=0;i<top;i++) { Info tmp = ans[i]; g[tmp.x][tmp.y] = tmp.num; } for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) putchar(g[i][j]+'0'); } const int maxlen = 100; char s[maxlen]; bool init() { scanf("%s",s); if(s[0]=='e') return false; initialize(); int pos=0; for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) { if(s[pos]!='.') insert_num(i,j,s[pos]-'0'); pos++; } pos=0; for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) { if(s[pos]=='.') insert_dot(i,j); pos++; } return true; } int main() { #ifndef ONLINE_JUDGE freopen("sudo.in","r",stdin); freopen("sudo.out","w",stdout); #endif bool flag = true; while(init()) { if(!flag) putchar('\n'); flag=false; Dance(mustselect); print(); } }
相关文章推荐
- POJ 3074 Sudoku DLX
- POJ 3074 Sudoku 转化精确覆盖问题DLX
- POJ 3074 Sudoku (DLX)
- DLX(精确覆盖) POJ 3074 Sudoku
- poj 3074 Sudoku (精确覆盖,DLX,搜索)
- POJ 3074 Sudoku (DLX解经典数独)
- POJ 3074 Sudoku(DLX+精确覆盖)
- (模板题)poj 3074 Sudoku(DLX算法)
- 搜索(DLX): POJ 3074 3076 Sudoku
- (简单) POJ 3074 Sudoku, DLX+精确覆盖。
- POJ 3074 Sudoku(数据结构,DLX)
- POJ 3074 Sudoku DLX精确覆盖
- POJ 3074 Sudoku DLX精确覆盖
- POJ 3074 Sudoku DLX
- 规则数独的计算机求解(POJ - 3074 Sudoku)
- poj 3074 Sudoku(Dancing Links)
- poj 3074(DLX)
- ACM练级日志:POJ 3074 数独与DLX
- POJ 3076 Sudoku (DLX)
- poj 3074 Sudoku