(模板题)poj 3074 Sudoku(DLX算法)
2017-04-11 10:03
423 查看
Sudoku
In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,
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 |
题意:
给出一组数独状态,你需要在'.'上填上数字来完成数独游戏。
思路:
可以将数独转化为精确覆盖问题,本文的源代码以及转化思想:http://blog.csdn.net/weiguang_123/article/details/7935003,思路也可参考:http://blog.csdn.net/bl0ss0m/article/details/17918705
精确覆盖问题的讲解和DLX算法详解:http://www.cnblogs.com/grenet/p/3145800.html,刘汝佳的算法竞赛入门经典训练指南p406也有提到过。
也可利用正规解数独的方法来DFS求解:http://blog.csdn.net/u011932355/article/details/45849039
示例程序
#include <cstdio> #include <cstring> using namespace std; int sum[325],l[237250],r[237250],u[237250],d[237250],c[237250],mplist[730][325],o[730],num,ans[10][10]; void remove(int x) { int i,i1; l[r[x]]=l[x]; r[l[x]]=r[x]; for(i=d[x];i!=x;i=d[i]) { for(i1=r[i];i1!=i;i1=r[i1]) { u[d[i1]]=u[i1]; d[u[i1]]=d[i1]; sum[c[i1]]--; } } } void resume(int x) { int i,i1; r[l[x]]=x; l[r[x]]=x; for(i=d[x];i!=x;i=d[i]) { for(i1=r[i];i1!=i;i1=r[i1]) { u[d[i1]]=i1; d[u[i1]]=i1; sum[c[i1]]++; } } } int dfs() { int i,i1,x,min; if(r[0]==0) { return 1; } min=1000000007; for(i=r[0];i!=0;i=r[i]) { if(sum[i]<min) { min=sum[i]; x=i; } } remove(x); for(i=d[x];i!=x;i=d[i]) { o[num]=(i-1)/324; num++; for(i1=r[i];i1!=i;i1=r[i1]) { remove(c[i1]); } if(dfs()==1) { return 1; } for(i1=l[i];i1!=i;i1=l[i1]) { resume(c[i1]); } num--; } resume(x); return 0; } int build() { int i,i1,pre,first,pos; num=0; for(i=0;324>i;i++) { r[i]=i+1; l[i+1]=i; } r[324]=0; l[0]=324; for(i=1;324>=i;i++) { pre=i; sum[i]=0; for(i1=1;729>=i1;i1++) { if(mplist[i1][i]==1) { sum[i]++; pos=i1*324+i; c[pos]=i; d[pre]=pos; u[pos]=pre; pre=pos; } } u[i]=pre; d[pre]=i; if(sum[i]==0) { return 0; } } for(i=1;729>=i;i++) { pre=-1; first=-1; for(i1=1;324>=i1;i1++) { if(mplist[i][i1]==1) { pos=i*324+i1; if(pre==-1) { first=pos; } else { r[pre]=pos; l[pos]=pre; } pre=pos; } } if(first!=-1) { r[pre]=first; l[first]=pre; } } return 1; } void output() { int i,i1,x,y,k,r,t; for(i=0;num>i;i++) { r=o[i]; k=r%9; if(k==0) { k=9; } t=(r-k)/9+1; y=t%9; if(y==0) { y=9; } x=(t-y)/9+1; ans[x][y]=k; } for(i=1;9>=i;i++) { for(i1=1;9>=i1;i1++) { printf("%d",ans[i][i1]); } } printf("\n"); } int main() { int i,i1,i2,top,t; char m[82]; while(scanf("%s",m)!=EOF&&strcmp(m,"end")!=0) { top=0; memset(mplist,0,sizeof(mplist)); for(i=1;9>=i;i++) { for(i1=1;9>=i1;i1++) { t=(i-1)*9+i1; if(m[top]=='.') { for(i2=1;9>=i2;i2++) { mplist[9*(t-1)+i2][t]=1; mplist[9*(t-1)+i2][81+(i-1)*9+i2]=1; mplist[9*(t-1)+i2][162+(i1-1)*9+i2]=1; mplist[9*(t-1)+i2][243+((i-1)/3*3+(i1+2)/3-1)*9+i2]=1; } } else { i2=m[top]-'0'; mplist[9*(t-1)+i2][t]=1; mplist[9*(t-1)+i2][81+(i-1)*9+i2]=1; mplist[9*(t-1)+i2][162+(i1-1)*9+i2]=1; mplist[9*(t-1)+i2][243+((i-1)/3*3+(i1+2)/3-1)*9+i2]=1; } top++; } } build(); dfs(); output(); } return 0; }
相关文章推荐
- POJ 3074 Sudoku DLX
- POJ 3074 Sudoku(DLX+精确覆盖)
- (简单) POJ 3074 Sudoku, DLX+精确覆盖。
- DLX(精确覆盖) POJ 3074 Sudoku
- POJ 3074 Sudoku (DLX解经典数独)
- POJ 3074 Sudoku [DLX] [SDLX]
- poj 3074 Sudoku (精确覆盖,DLX,搜索)
- POJ 3074 Sudoku DLX
- POJ 3074 Sudoku 转化精确覆盖问题DLX
- dancing links 算法学习小记 Poj 3074 Sudoku (数独)
- 搜索(DLX): POJ 3074 3076 Sudoku
- POJ 3074 Sudoku (DLX)
- POJ 3074 Sudoku DLX精确覆盖
- POJ 3074 Sudoku DLX精确覆盖
- POJ 3074 Sudoku(数据结构,DLX)
- poj 3074(DLX)
- poj 3164 最小树形图模板题目,朱刘算法
- 计算几何--求凸包模板--Graham算法--poj 1113
- Graham 扫描算法求凸包,poj 2187(水题但是是我的第一个求n点集凸包模板)
- POJ 3076 Sudoku (DLX)