大致题意:每个多米诺骨牌可能横着,也可能竖着,请你判断有哪些合法的摆放方式。
这题的dfs需要注意一下,不能以某个点直接开始延伸,如果这样延伸可能会无法到达终点(也就是遍历全图)。我的dfs方法就是枚举每一行,一行枚举完了进入下一行。
AC代码:
#include<cstring>
#include<cstdio>
const int maxn=8;
int bone[maxn][maxn],pip[maxn][maxn],ans[maxn][maxn];
int vis[30];
int dx[]={0,1};
int dy[]={1,0};
void init(){
int val=1;
for(int i=0;i<=6;++i){
for(int j=i;j<=6;++j)
bone[i][j]=bone[j][i]=val++;
}
}
int cnt=0;
void dfs(int d,int x,int y){
if(d==28){
cnt++;
for(int i=0;i<7;++i){
for(int j=0;j<8;++j){
printf(" %2d",ans[i][j]);
}
printf("\n");
}
printf("\n\n");
return;
}
if(y==8) {dfs(d,x+1,0);return;}
if(ans[x][y]) {dfs(d,x,y+1);return;}
for(int i=0;i<2;++i){
int newx=x+dx[i],newy=y+dy[i];
if(newx<0||newx>=7||newy<0||newy>=8) continue;
if(ans[newx][newy]) continue;
int v1=pip[x][y],v2=pip[newx][newy];
int key=bone[v1][v2];
if(vis[key]) continue;
ans[x][y]=ans[newx][newy]=key;
vis[key]=1;
dfs(d+1,x,y+1);
ans[x][y]=ans[newx][newy]=0;
vis[key]=0;
}
}
int main(){
init();
int e,kase=1;
while(scanf("%d",&e)==1){
if(kase>1) printf("\n\n\n");
memset(vis,0,sizeof(vis));
memset(ans,0,sizeof(ans));
cnt=0;
for(int i=0;i<7;++i)
for(int j=0;j<8;++j){
if(i==0&&j==0) pip[i][j]=e;
else scanf("%d",&pip[i][j]);
}
printf("Layout #%d:\n\n\n",kase);
for(int i=0;i<7;++i){
for(int j=0;j<8;++j)
printf(" %2d",pip[i][j]);
printf("\n");
}
printf("\n");
printf("Maps resulting from layout #%d are:\n\n\n",kase);
dfs(0,0,0);
printf("There are %d solution(s) for layout #%d.\n",cnt,kase++);
}
return 0;
}
如有不当之处欢迎指出!