题意:点数为1~28的多米诺骨牌有一个数对作为编号,每张多米诺骨牌假设占地1*2,输入一个7*8的平面,平面上的每一个电商有一个数字,相邻的两个格子上的数字组成的数对上可以放一张编号相同的骨牌。输出在用1~28的骨牌各一张铺满这个平面的所有情况。
思路:dfs。枚举每个骨牌放在哪两个格子上。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#include<algorithm>
#include<sstream>
#include<queue>
#include<set>
using namespace std;
#define w 7
#define h 8
#define n 28
struct Pair {
int x,y;
Pair() {}
Pair(int one,int two) {
x=one,y=two;
}
bool operator ==(const Pair& other) const {
if(x==other.x&&y==other.y) return true;
return false;
}
};
Pair mp[n+5];
int See[w+5][h+5]= {0};
int a[w+5][h+5]= {0};
int cnt=0;
int T=0;
void make() {
int k=0;
for(int i=0; i<=6; i++) {
for(int j=i; j<=6; j++) {
mp[++k]=Pair(i,j);
}
}
}
bool init() {
cnt=0;
memset(a,0,sizeof(a));
if(scanf("%d",&See[1][1])!=1) return false;
for(int i=1; i<=w; i++) {
for(int j=1; j<=h; j++) {
if(i!=1||j!=1)
scanf("%d",&See[i][j]);
}
}
return true;
}
void dfs(int step) {
if(step>n) {
for(int i=1; i<=w; i++) {
for(int j=1; j<=h; j++) {
printf("%4d",a[i][j]);
}
printf("\n");
}
printf("\n\n");
cnt++;
return ;
}
Pair t=mp[step];
for(int i=1; i<=w; i++) {
for(int j=1; j<=h; j++) {
if(!a[i][j]) {
if(i-1>0&&!a[i-1][j]) {
if(t==Pair(See[i][j],See[i-1][j])||t==Pair(See[i-1][j],See[i][j])) {
a[i][j]=a[i-1][j]=step;
dfs(step+1);
a[i][j]=a[i-1][j]=0;
}
}
if(j-1>0&&!a[i][j-1]) {
if(t==Pair(See[i][j],See[i][j-1])||t==Pair(See[i][j-1],See[i][j])) {
a[i][j]=a[i][j-1]=step;
dfs(step+1);
a[i][j]=a[i][j-1]=0;
}
}
}
}
}
return ;
}
int main() {
make();
while(init()) {
++T;
if(T!=1) printf("\n\n\n\n\n");
printf("Layout #%d:\n\n\n",T);
for(int i=1; i<=w; i++) {
for(int j=1; j<=h; j++) {
printf("%4d",See[i][j]);
}
printf("\n");
}
printf("\n");
printf("Maps resulting from layout #%d are:\n\n\n",T);
dfs(1);
printf("There are %d solution(s) for layout #%d.\n",cnt,T);
}
return 0;
}