poj3074,3076 数独!(DLX)
来源:互联网 发布:淘宝客佣金套路 编辑:程序博客网 时间:2024/05/22 13:50
大意:求解规模为9*9的数独问题分析:对于每一行,每一列,每一宫,数字1,2。。。9都需出现1次且只能是一次,可转化为精确覆盖问题,用跳舞链解决
建模型:行数为9*9*9,数独中,第i行j列放数字k的状态存储在图中第(i*9+j)*9+k行中列数为9*9+9*9+9*9+9*9,
其中第一个9*9代表第i格是否已填满,如果已经填了,有且仅有一个g[cur][i*9+j]=1;否则会有1-9共9个,用精确覆盖再决策,这样能保证每格都被填充。用第二个9*9确保每行的数字唯一且均出现一次 g[cur][81+i*9+k]=1表示第i行能够填k第三个9*9确保每列的数字唯一且出现一次第四个9*9确保每宫的数字唯一出现1次
#include<stdio.h>#include<string.h>#define MAXN 1050int n,m;int U[MAXN*MAXN];int D[MAXN*MAXN];int L[MAXN*MAXN];int R[MAXN*MAXN];int C[MAXN*MAXN]; //to see node[i] belong to which columnint row[MAXN*MAXN]; // to see node[i] belong to which rowint ans[MAXN],ansnum;int nn[MAXN];int mm[MAXN];bool map[MAXN][MAXN];const int head=0;char str[100];void read_data(){ memset(mm,0,sizeof(mm)); for(int i=1;i<=m;i++){ R[i-1]=L[i+1]=U[i]=D[i]=i; } R[m]=0; R[head]=1; int id=m+1; int x,Rhead; for(int i=0;i<n;i++){ Rhead=-1; for(int j=0;j<m;j++){ if(map[i][j]==true){ x=j+1; mm[x]++; row[id]=i; C[id]=x; //update the column U[id]=U[x]; D[U[x]]=id; U[x]=id; D[id]=x; //update the row if(Rhead==-1){ L[id]=R[id]=id; Rhead=id; } else { L[id]=L[Rhead]; R[L[Rhead]]=id; L[Rhead]=id; R[id]=Rhead; } id++; } } }}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]; mm[C[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]){ mm[C[j]]++; U[D[j]]=j; D[U[j]]=j; } } L[R[c]]=c; R[L[c]]=c;}bool dfs(int cur){ if(R[head]==head){ return true; } int s=999999999,c; for(int t=R[head];t!=head;t=R[t]){ if(mm[t]<s){ s=mm[t]; c=t; } } remove(c); for(int i=D[c];i!=c;i=D[i]){ ans[row[i]]=true; for(int j=R[i];j!=i;j=R[j]){ remove(C[j]); } if(dfs(cur+1))return true; ans[row[i]]=false; for(int j=L[i];j!=i;j=L[j]){ resume(C[j]); } } resume(c); return false;}void addrow(int i,int j,int k){ int cur=(i*9+j)*9+k; map[cur][i*9+j]=true; map[cur][81+i*9+k]=true; map[cur][81+81+j*9+k]=true; int rc=i/3; int lc=j/3; map[cur][81+81+81+(rc*3+lc)*9+k]=true;}void build_graph(){ memset(map,false,sizeof(map)); for(int i=0;i<81;i++){ if(str[i]=='.'){ int a=i/9; int b=i%9; for(int k=0;k<9;k++)addrow(a,b,k); } else { int a=i/9; int b=i%9; addrow(a,b,str[i]-'1'); } }}void solve(){ build_graph(); read_data(); memset(ans,false,sizeof(ans)); dfs(0); for(int i=0;i<9;i++){ for(int j=0;j<9;j++){ for(int k=0;k<9;k++) if(ans[(i*9+j)*9+k])printf("%d",k+1); } } printf("\n");}int main(){ n=9*9*9; m=(81+9*9+9*9+9*9); //first 81 present 81 grids;next 9*9 present line ,column,blocks state; while(scanf("%s",str)!=EOF){ if(strcmp(str,"end")==0)break; solve(); }}
- poj3074,3076 数独!(DLX)
- poj3074 9*9数独,poj3076 16*16数独 DLX
- poj3074 & 3076 数独 Dancing Links
- poj3074/3076 Dancing Links (数独)
- poj3074(数独)
- POJ3074 sudoku数独
- POJ 3076 数独DLX
- poj3074 poj3076 数独问题 dancing links
- DLX(变形数独)hdu4069
- uva 1309 数独【DLX】
- poj3074/3076 Dancing Links 解数独
- 【poj3074】【DLX】sudoku
- DLX之数独问题的解决
- DLX解 各种规模数独
- poj3074Sudoku(DLX解9*9数独)
- poj 2676 dfs/DLX(数独)
- POJ 2676 数独 Dancing-Links(DLX)
- 【位运算DFS/DLX】【HDU1426】【数独】
- 国嵌视频学习第三天-进程控制
- 寻找发帖水王
- 一个苏州IT人的5年挨踢经历-------经历篇(之三)
- 常见HTTP状态(304,200等)
- java web 类介绍
- poj3074,3076 数独!(DLX)
- DW中出现 "以下翻译器没有被装载,由于错误:xxxx.htm:有不正确的设置信息" 问题的解决方案
- Android禁止横屏竖屏切换
- ODI Lab
- lucene全文检索初体验-lucene demo演示
- ICONIX by Rosenberg
- 第八周实验报告 任务二
- ODI相关文档链接
- .NET进行异常处理时的原则注意事项