求解瓷砖样式问题
【问题描述】
有2种不同颜色规格为1 * 2的瓷砖,用其来铺设地板,不能重叠和越界。并且,地板中任意2 * 2的格子不能为同一种颜色。如图,当地板为2 * 3时,有10种铺设方案。问:当地板为3 * 10时,问有多少种铺设方案?
详细题目参考blog
【问题求解】
由于数据规模并不算大,直接dfs就可以了,深搜的过程中注意下放瓷砖的规则,比如从左到右,从上到下,当然也可以按照自己的来。
【代码】
- dfs方法
//瓷砖样式
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<map>
using namespace std;
const int maxn=10+5;
int mp[maxn][maxn];
int row,col,ans=0;
map<string,int> dict;
bool check() {
for(int i=0; i<row-1; i++)
for(int j=0; j<col-1; j++)
if((mp[i][j]+mp[i+1][j]+mp[i][j+1]+mp[i+1][j+1])%4==0)
return false;
string s;
for(int i=0; i<row; i++)
for(int j=0; j<col; j++)
s+='0'+mp[i][j];
if(!dict.count(s)) {
dict[s]=1;
return true;
} else return false;
}
void dfs(int m,int n) {
if(mp[m][n]==-1) {
if(n+1<col && mp[m][n+1]==-1) {
for(int i=0; i<2; i++) {
mp[m][n]=mp[m][n+1]=i+1;
dfs(m,n+1);
}
mp[m][n]=mp[m][n+1]=-1;
}
if(m+1<row && mp[m+1][n]==-1) {
for(int i=0; i<2; i++) {
mp[m][n]=mp[m+1][n]=i+1;
if(n==col-1) dfs(m+1,0);
else dfs(m,n+1);
}
mp[m][n]=mp[m+1][n]=-1;
}
} else {
if(m==row-1 && n==col-1) {
if(check()) {
// for(int i=0; i<row; i++) {
// for(int j=0; j<col; j++)
// cout<<mp[i][j]<<" ";
// cout<<endl;
// }
// cout<<endl;
ans++;
}
return;
}
if(n==col-1) dfs(m+1,0);
else dfs(m,n+1);
}
}
int main() {
memset(mp,-1,sizeof(mp));
cin>>row>>col;
dfs(0,0);
cout<<ans<<endl;
return 0;
}
2021-04-12 感谢观看-