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 }
View Code

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 }
View Code

题目链接:

http://poj.org/problem?id=3074

http://acm.hdu.edu.cn/showproblem.php?pid=1426

posted on 2015-04-23 22:17  xiao_xin  阅读(140)  评论(0编辑  收藏  举报

导航