首页 > 代码库 > HDU 3111 Sudoku(精确覆盖)
HDU 3111 Sudoku(精确覆盖)
数独问题,输入谜题,输出解
既然都把重复覆盖的给写成模板了,就顺便把精确覆盖的模板也写好看点吧。。。赤裸裸的精确覆盖啊~~~水一水~~~然后继续去搞有点难度的题了。。。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <cmath> 6 #include <string> 7 #include <vector> 8 #include <queue> 9 #include <set> 10 using namespace std; 11 12 #define ll long long 13 #define eps 1e-8 14 #define mod 21092013 15 16 #define inf 0x3f3f3f3f 17 #define maxr 777 18 #define maxn (maxr*maxr) 19 int n,m; 20 int L[maxn],R[maxn],U[maxn],D[maxn],cnt; 21 int row[maxn],col[maxn]; 22 int N[maxr],use[maxr],head[maxr]; 23 void init(){ 24 memset(head,-1,sizeof(head)); 25 memset(N,0,sizeof(N)); 26 for(int i=0;i<=m;++i){ 27 L[i]=i-1,R[i]=i+1; 28 U[i]=D[i]=i; 29 row[i]=0,col[i]=i; 30 } 31 L[0]=m,R[m]=0; 32 cnt=m; 33 } 34 void remove(int c){// 删除列以及所在列含有1的行 35 L[R[c]]=L[c],R[L[c]]=R[c]; 36 for(int i=D[c];i!=c;i=D[i]) 37 for(int j=R[i];j!=i;j=R[j]) 38 U[D[j]]=U[j],D[U[j]]=D[j],--N[col[j]]; 39 } 40 void resume(int c){// 恢复列以及所在列含有1的行 41 for(int i=U[c];i!=c;i=U[i]) 42 for(int j=L[i];j!=i;j=L[j]) 43 U[D[j]]=D[U[j]]=j,++N[col[j]]; 44 L[R[c]]=R[L[c]]=c; 45 } 46 int low(){ 47 int mi=maxr,idx=0; 48 for(int i=R[0];i;i=R[i])if(N[i]<mi&&N[i])mi=N[i],idx=i; 49 return idx; 50 } 51 void link(int r,int c){ 52 ++N[c],++cnt; 53 row[cnt]=r,col[cnt]=c; 54 U[cnt]=U[c],D[cnt]=c; 55 U[D[cnt]]=D[U[cnt]]=cnt; 56 if(head[r]==-1) 57 head[r]=L[cnt]=R[cnt]=cnt; 58 else { 59 L[cnt]=L[head[r]]; 60 R[cnt]=head[r]; 61 L[R[cnt]]=R[L[cnt]]=cnt; 62 } 63 } 64 int xy[maxr][2];char num[maxr]; 65 char ch[12][12]; 66 bool dance(int dep){ 67 if(R[0]==0)return true; 68 int c=low(); 69 if(c==0)return false; 70 for(int i=D[c];i!=c;i=D[i]){ 71 int r=row[i]; 72 ch[xy[r][0]][xy[r][1]]=num[r]; 73 use[dep]=i; 74 remove(col[i]); 75 for(int j=R[i];j!=i;j=R[j])remove(col[j]); 76 if(dance(dep+1))return true; 77 for(int j=L[i];j!=i;j=L[j])resume(col[j]); 78 resume(col[i]); 79 } 80 return false; 81 } 82 83 int main(){ 84 int t,ca=0; 85 scanf("%d",&t); 86 while(t--){ 87 if(ca)scanf("%s",ch[0]); 88 if(ca)puts("---"); 89 ca=1; 90 n=0,m=324; 91 init(); 92 for(int i=1;i<=9;++i)scanf("%s",ch[i]+1); 93 for(int i=1;i<=9;++i){ 94 for(int j=1;j<=9;++j){ 95 if(ch[i][j]>=‘0‘&&ch[i][j]<=‘9‘){ 96 int val=ch[i][j]-‘0‘; 97 ++n; 98 link(n,(i-1)*9+val); 99 link(n,81+(j-1)*9+val); 100 link(n,162+(i-1)*9+j); 101 link(n,243+((i-1)/3*3+(j+2)/3-1)*9+val ); 102 xy[n][0]=i,xy[n][1]=j; 103 num[n]=val+‘0‘; 104 } 105 else { 106 for(int k=1;k<=9;++k){ 107 int val=k; 108 ++n; 109 link(n,(i-1)*9+val); 110 link(n,81+(j-1)*9+val); 111 link(n,162+(i-1)*9+j); 112 link(n,243+((i-1)/3*3+(j+2)/3-1)*9+val ); 113 xy[n][0]=i,xy[n][1]=j; 114 num[n]=val+‘0‘; 115 } 116 } 117 } 118 } 119 if(dance(0))for(int i=1;i<=9;++i)printf("%s\n",ch[i]+1); 120 else puts("impossible"); 121 } 122 return 0; 123 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。