题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4210

Dancing Links + dfs。

额,好像又有一段时间没更新博客了,最近比较忙,上周校赛终于圆满结束了,我这一颗心也终于能放下来了。

上周还有一些另外收获,先保密吧 ^_^

这周本来不准备去武汉参加比赛的,想在五一的时候好好出去玩玩,但由于种种原因吧, 老师还是决定让我们这队去。哎,压力又是不小啊。

这几天抓紧集训一下,希望能找回一些状态。

上周就看过这道题目,当时没仔细读,以为给出的骨牌没什么用,就是一个很裸的数独问题,今天写好了代码,发现结果和给出的样例不太一样。

又读了读题目,发现原来需要判断能否用骨牌拼接并且每种骨牌只能用一次。这就增加了题目难度,每找到一种合适的数独,就需要再判断是否满足

骨牌的要求,我是用dfs来判断是否满足要求的。

code:(好长时间没写Dancing Links,又查了好多次模板)

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

 

 

posted on 2012-04-24 16:05  奋斗青春  阅读(451)  评论(0编辑  收藏  举报