题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4210
Dancing Links + dfs。
额,好像又有一段时间没更新博客了,最近比较忙,上周校赛终于圆满结束了,我这一颗心也终于能放下来了。
上周还有一些另外收获,先保密吧 ^_^
这周本来不准备去武汉参加比赛的,想在五一的时候好好出去玩玩,但由于种种原因吧, 老师还是决定让我们这队去。哎,压力又是不小啊。
这几天抓紧集训一下,希望能找回一些状态。
上周就看过这道题目,当时没仔细读,以为给出的骨牌没什么用,就是一个很裸的数独问题,今天写好了代码,发现结果和给出的样例不太一样。
又读了读题目,发现原来需要判断能否用骨牌拼接并且每种骨牌只能用一次。这就增加了题目难度,每找到一种合适的数独,就需要再判断是否满足
骨牌的要求,我是用dfs来判断是否满足要求的。
code:(好长时间没写Dancing Links,又查了好多次模板)
1 # include<stdio.h> 2 # include<string.h> 3 # include<stdlib.h> 4 # define RR 750 5 # define CC 350 6 # define V RR*CC 7 int U[V],D[V]; 8 int L[V],R[V]; 9 int C[V],ROW[V]; 10 int H[RR],S[CC]; 11 int size; 12 int map[10][10]; 13 int hash1[RR],hash2[RR],hash[RR],OK[90]; 14 int visit[12][12],vis[12][12]; 15 int dir[2][2]={0,1,1,0}; 16 void Link(int r,int c) 17 { 18 S[c]++;C[size]=c; 19 ROW[size]=r; 20 U[size]=U[c];D[U[c]]=size; 21 D[size]=c;U[c]=size; 22 if(H[r]==-1) H[r]=L[size]=R[size]=size; 23 else 24 { 25 L[size]=L[H[r]];R[L[H[r]]]=size; 26 R[size]=H[r];L[H[r]]=size; 27 } 28 size++; 29 } 30 void remove1(int c) 31 { 32 int i,j; 33 L[R[c]]=L[c]; 34 R[L[c]]=R[c]; 35 for(i=D[c];i!=c;i=D[i]) 36 { 37 for(j=R[i];j!=i;j=R[j]) 38 { 39 S[C[j]]--; 40 U[D[j]]=U[j]; 41 D[U[j]]=D[j]; 42 } 43 } 44 } 45 void resume1(int c) 46 { 47 int i,j; 48 for(i=U[c];i!=c;i=U[i]) 49 { 50 for(j=L[i];j!=i;j=L[j]) 51 { 52 S[C[j]]++; 53 U[D[j]]=D[U[j]]=j; 54 } 55 } 56 R[L[c]]=L[R[c]]=c; 57 } 58 int dfs(int step) 59 { 60 int i,j,k,temp,nextx,nexty; 61 int ans1,ans2,ans; 62 if(step==82) return 1; 63 i=(step-1)/9+1; 64 j=step-(i-1)*9; 65 if(vis[i][j]) 66 { 67 return dfs(step+1); 68 } 69 else 70 { 71 for(k=0;k<=1;k++) 72 { 73 nextx=i+dir[k][0]; 74 nexty=j+dir[k][1]; 75 if(nextx<=9 && nexty<=9 && vis[nextx][nexty]==0) 76 { 77 ans1=map[i][j]; 78 ans2=map[nextx][nexty]; 79 if(ans1>ans2) 80 { 81 temp=ans1; 82 ans1=ans2; 83 ans2=temp; 84 } 85 if(visit[ans1][ans2]==0) 86 { 87 vis[i][j]=1; 88 vis[nextx][nexty]=1; 89 visit[ans1][ans2]=1; 90 ans=dfs(step+1); 91 if(ans==1) return 1; 92 vis[i][j]=0; 93 vis[nextx][nexty]=0; 94 visit[ans1][ans2]=0; 95 } 96 } 97 } 98 return 0; 99 } 100 } 101 int check() 102 { 103 int i; 104 for(i=0;i<81;i++) 105 map[hash1[OK[i]]][hash2[OK[i]]]=hash[OK[i]]; 106 return dfs(1); 107 } 108 int Dance(int k) 109 { 110 int i,j,Min,c; 111 if(!R[0]) 112 { 113 if(check()) return 1; 114 return 0; 115 } 116 for(Min=RR,i=R[0];i;i=R[i]) 117 if(Min>S[i]) Min=S[i],c=i; 118 remove1(c); 119 for(i=D[c];i!=c;i=D[i]) 120 { 121 for(j=R[i];j!=i;j=R[j]) 122 remove1(C[j]); 123 OK[k]=ROW[i]; 124 if(Dance(k+1)) return 1; 125 for(j=L[i];j!=i;j=L[j]) 126 resume1(C[j]); 127 } 128 resume1(c); 129 return 0; 130 } 131 int main() 132 { 133 int i,j,n,k,t=0,r; 134 int ans1,ans2,ii,jj,temp; 135 char ch1[5],ch2[5]; 136 while(scanf("%d",&n)!=EOF && n) 137 { 138 t++; 139 for(i=0;i<=324;i++) 140 { 141 S[i]=0; 142 D[i]=U[i]=i; 143 L[i+1]=i; 144 R[i]=i+1; 145 }R[324]=0; 146 size=325; 147 r=0; 148 memset(map,0,sizeof(map)); 149 memset(H,-1,sizeof(H)); 150 memset(visit,0,sizeof(visit)); 151 memset(vis,0,sizeof(vis)); 152 for(i=0;i<n;i++) 153 { 154 scanf("%d%s%d%s",&ans1,ch1,&ans2,ch2); 155 ii=ch1[0]-'A'+1; 156 jj=ch1[1]-'0'; 157 map[ii][jj]=ans1; 158 vis[ii][jj]=1; 159 160 ii=ch2[0]-'A'+1; 161 jj=ch2[1]-'0'; 162 map[ii][jj]=ans2; 163 vis[ii][jj]=1; 164 165 if(ans1>ans2) 166 { 167 temp=ans1; 168 ans1=ans2; 169 ans2=temp; 170 } 171 visit[ans1][ans2]=1; 172 } 173 for(i=1;i<=9;i++) 174 { 175 scanf("%s",ch1); 176 ii=ch1[0]-'A'+1; 177 jj=ch1[1]-'0'; 178 map[ii][jj]=i; 179 vis[ii][jj]=1; 180 } 181 for(i=1;i<=9;i++) 182 { 183 for(j=1;j<=9;j++) 184 { 185 if(map[i][j]!=0) 186 { 187 r++; 188 hash1[r]=i; 189 hash2[r]=j; 190 hash[r]=map[i][j]; 191 Link(r,(i-1)*9+j); 192 Link(r,81+(i-1)*9+map[i][j]); 193 Link(r,162+(j-1)*9+map[i][j]); 194 Link(r,243+((i-1)/3)*27 + ((j-1)/3)*9+map[i][j]); 195 } 196 else 197 { 198 for(k=1;k<=9;k++) 199 { 200 r++; 201 hash1[r]=i; 202 hash2[r]=j; 203 hash[r]=k; 204 Link(r,(i-1)*9+j); 205 Link(r,81+(i-1)*9+k); 206 Link(r,162+(j-1)*9+k); 207 Link(r,243+(i-1)/3*27 + (j-1)/3*9 + k); 208 } 209 } 210 } 211 }/// 212 Dance(0); 213 /*for(i=0;i<81;i++) 214 { 215 map[hash1[OK[i]]][hash2[OK[i]]]=hash[OK[i]]; 216 }*/ 217 printf("Puzzle %d\n",t); 218 for(i=1;i<=9;i++) 219 { 220 for(j=1;j<=9;j++) 221 printf("%d",map[i][j]); 222 printf("\n"); 223 } 224 } 225 return 0; 226 }