原题链接:https://vjudge.net/problem/UVA-211
分类:回溯法
备注:水题,注意格式
28张牌,每张牌有两个数字,放到一个7*8的网格内,要求网格的数字与牌的数字一一对应,每张牌占据两个网格,可以横放或竖放。
#include<bits/stdc++.h>
using namespace std;
struct Bone{
int pip[2];
}b[30];
int layout[10][10];
int ans[10][10],cnt;
inline bool check(int id,int x1,int y1,int x2,int y2){
if(b[id].pip[0]==layout[x1][y1]&&b[id].pip[1]==layout[x2][y2])return true;
if(b[id].pip[1]==layout[x1][y1]&&b[id].pip[0]==layout[x2][y2])return true;
return false;
}
void dfs(int id){
//printf("id=%d\n",id);
if(id==29){
printf("\n\n");
for(int i=1;i<=7;i++){
for(int j=1;j<=8;j++){
printf("%4d",ans[i][j]);
}
printf("\n");
}
cnt++;
return;
}
for(int i=1;i<=7;i++){
for(int j=1;j<=8;j++){
if(ans[i][j])continue;
if(j!=8&&!ans[i][j+1]){//水平
if(check(id,i,j,i,j+1)){
ans[i][j]=ans[i][j+1]=id;
dfs(id+1);
ans[i][j]=ans[i][j+1]=0;
}
}
if(i!=7&&!ans[i+1][j]){//垂直
if(check(id,i,j,i+1,j)){
ans[i][j]=ans[i+1][j]=id;
dfs(id+1);
ans[i][j]=ans[i+1][j]=0;
}
}
}
}
}
int main(void){
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int id=0;
for(int i=0;i<=6;i++){
for(int j=i;j<=6;j++){
id++;
b[id].pip[0]=i;
b[id].pip[1]=j;
}
}
int kase=0;
while(~scanf("%d",&layout[1][1])){
for(int i=2;i<=8;i++)scanf("%d",&layout[1][i]);
for(int i=2;i<=7;i++)for(int j=1;j<=8;j++)scanf("%d",&layout[i][j]);
if(kase)printf("\n\n\n\n\n");
printf("Layout #%d:\n\n\n",++kase);
for(int i=1;i<=7;i++){
for(int j=1;j<=8;j++){
printf("%4d",layout[i][j]);
}
printf("\n");
}
printf("\nMaps resulting from layout #%d are:\n",kase);
cnt=0; dfs(1);
printf("\n\nThere are %d solution(s) for layout #%d.\n",cnt,kase);
}
return 0;
}