hdu1426/poj3074 数独:DLX精准覆盖
之前就听说过数独用DLX解较方便,今天学习了==
建立一个N=n*n*n M=n*n*4的bool矩阵,然后跑DLX,这个建图学习了bin巨的,感觉好厉害==
对于每一个位置,每放一种数字,都对应要覆盖四个东西-->该位置有这个数字,该行有这个数字,该列有这个数字,该方块有这个数字 think
话说,hdu1426这道当时是用dfs写的,卧槽竟然跑的比DLX快了一点2333
poj3074:
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 struct DLX{ 6 int n,m,size,ansd,ans[1005]; 7 int U[4005],D[4005],L[4005],R[4005]; 8 int Row[40005],Col[40005],H[1005],S[1005]; 9 void init(int _n,int _m){ 10 n=_n; m=_m; 11 for (int i=0;i<=m;i++){ 12 S[i]=0; 13 U[i]=D[i]=i; 14 L[i]=i-1; R[i]=i+1; 15 } 16 R[m]=0; L[0]=m; 17 size=m; 18 for (int i=1;i<=n;i++) H[i]=-1; 19 } 20 void link(int r,int c){ 21 S[c]++; 22 Col[++size]=c; Row[size]=r; 23 D[size]=D[c]; U[D[c]]=size; 24 U[size]=c; D[c]=size; 25 if (H[r]<0) H[r]=L[size]=R[size]=size; 26 else{ 27 R[size]=R[H[r]]; 28 L[R[H[r]]]=size; 29 L[size]=H[r]; 30 R[H[r]]=size; 31 } 32 } 33 void remove(int c){ 34 L[R[c]]=L[c]; R[L[c]]=R[c]; 35 for (int i=D[c];i!=c;i=D[i]) 36 for (int j=R[i];j!=i;j=R[j]){ 37 U[D[j]]=U[j]; 38 D[U[j]]=D[j]; 39 S[Col[j]]--; 40 } 41 } 42 void resume(int c){ 43 for (int i=U[c];i!=c;i=U[i]) 44 for (int j=L[i];j!=i;j=L[j]){ 45 U[D[j]]=D[U[j]]=j; 46 S[Col[j]]++; 47 } 48 L[R[c]]=R[L[c]]=c; 49 } 50 int a[105]; 51 int dance(int d){ 52 if (R[0]==0){ 53 ansd=d; 54 for (int i=0;i<d;i++) a[(ans[i]-1)/9]=(ans[i]-1)%9+1; 55 for (int i=0;i<81;i++) printf("%d",a[i]); 56 printf("\n"); 57 return 1; 58 } 59 int c=R[0]; 60 for (int i=R[0];i;i=R[i]) 61 if (S[i]<S[c]) c=i; 62 remove(c); 63 for (int i=D[c];i!=c;i=D[i]){ 64 ans[d]=Row[i]; 65 for (int j=R[i];j!=i;j=R[j]) remove(Col[j]); 66 if (dance(d+1)) return 1; 67 for (int j=L[i];j!=i;j=L[j]) resume(Col[j]); 68 } 69 resume(c); 70 return 0; 71 } 72 }; 73 DLX g; 74 int main() 75 { 76 int r,c1,c2,c3,c4,i,j,k; 77 char s[105]; 78 while (~scanf("%s",s)){ 79 if (s[0]=='e') break; 80 g.init(9*9*9,9*9*4); 81 for (i=0;i<9;i++) 82 for (j=0;j<9;j++) 83 for (k=1;k<=9;k++) 84 if (s[i*9+j]=='.'||s[i*9+j]=='0'+k) 85 { 86 r=(i*9+j)*9+k; 87 c1=i*9+j+1; 88 c2=9*9+(i*9)+k; 89 c3=2*9*9+(j*9)+k; 90 c4=3*9*9+((i/3)*3+j/3)*9+k; 91 g.link(r,c1); g.link(r,c2); 92 g.link(r,c3); g.link(r,c4); 93 } 94 g.dance(0); 95 } 96 return 0; 97 }
hdu1426和poj3074的DLX代码差不多,不贴了,贴一个当年的dfs写的代码:
1 #include <stdio.h> 2 int sum,map[105][105],x[105],y[105],t; 3 int judge(int p,int q) 4 { 5 int i,j,tx=(x[p]-1)/3*3+1,ty=(y[p]-1)/3*3+1; 6 for (i=1;i<=9;i++) 7 if (map[x[p]][i]==q||map[i][y[p]]==q) return(0); 8 for (i=tx;i<=tx+2;i++) 9 for (j=ty;j<=ty+2;j++) 10 if (map[i][j]==q) return(0); 11 return(1); 12 } 13 void dfs(int p) 14 { 15 int i; 16 if (p>sum) {t=1; return; } 17 for (i=1;i<=9;i++) 18 if (judge(p,i)==1&&t==0) 19 { 20 map[x[p]][y[p]]=i; 21 dfs(p+1); 22 if (t!=1) map[x[p]][y[p]]=0; 23 } 24 return; 25 } 26 int main() 27 { 28 int k=0,i,j; 29 char ch[105][105]; 30 while (gets(ch[1])) 31 { 32 if (k!=0) gets(ch[1]); k++; 33 for (i=2;i<=9;i++) gets(ch[i]); 34 sum=0; 35 for (i=1;i<=9;i++) 36 for (j=1;j<=9;j++) 37 if (ch[i][2*j-2]!='?') map[i][j]=ch[i][2*j-2]-'0'; 38 else{ 39 map[i][j]=0; 40 sum++; 41 x[sum]=i; y[sum]=j; 42 } 43 t=0; dfs(1); 44 if (k!=1) printf("\n"); 45 for (i=1;i<=9;i++) 46 { 47 printf("%d",map[i][1]); 48 for (j=2;j<=9;j++) printf(" %d",map[i][j]); 49 printf("\n"); 50 } 51 } 52 return(0); 53 }
题目链接: