小明家的一面装饰墙原来是 3*10 的小方格。
现在手头有一批刚好能盖住2个小方格的长方形瓷砖。
瓷砖只有两种颜色:黄色和橙色。
小明想知道,对于这么简陋的原料,可以贴出多少种不同的花样来。
小明有个小小的强迫症:忍受不了任何2*2的小格子是同一种颜色。
(瓷砖不能切割,不能重叠,也不能只铺一部分。另外,只考虑组合图案,请忽略瓷砖的拼缝)
显然,对于 2*3 个小格子来说,口算都可以知道:一共10种贴法,如【p1.png所示】
但对于 3*10 的格子呢?肯定是个不小的数目,请你利用计算机的威力算出该数字。
注意:你需要提交的是一个整数,不要填写任何多余的内容(比如:说明性文字)
这题由于有一个坑,只考虑组合图案,不考虑缝隙,就会产生重复。比如一个
所以使用hush来去重,而且我发现我的dfs好像还是有一点不熟练。。。
#include <iostream>
#include<cstring>
#include<map>
#define LL long long
using namespace std;
int mp[10][20];
map<LL ,LL> hush;
int m,n,ans = 0;
bool judge(){
for(int i =0;i<n-1;i++){
for(int j=0;j<m-1;j++){
if(mp[i][j] == 0 || mp[i+1][j+1] == 0)
return false;
int tmp = mp[i][j];
if(tmp == mp[i+1][j] && tmp == mp[i][j+1] && tmp == mp[i+1][j+1])
return false;
}
}
return true;
}
void show(){
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cout<<mp[i][j]<<' ';
}
cout<<endl;
}
cout<<endl;
}
void dfs(int x,int y){
if(y >= m){
dfs(x+1,0);
return;
}
if(mp[x][y]){
dfs(x,y+1);
return;
}
if(x == n){
if(judge()){
LL sum = 0;
LL bits = 1;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
sum+=mp[i][j] * bits;
bits <<= 1;
}
}
if(hush[sum] == 0){
hush[sum] = 1;
ans++;
}
}
return;
}
if(y+1 < m && mp[x][y+1] == 0 && mp[x][y] == 0){
mp[x][y+1] = 1;
mp[x][y] = 1;
dfs(x,y+1);
mp[x][y+1] = 2;
mp[x][y] = 2;
dfs(x,y+1);
mp[x][y+1] = 0;
mp[x][y] = 0;
}
if(x+1 < n && mp[x+1][y] == 0 && mp[x][y] == 0){
mp[x+1][y] = 1;
mp[x][y] = 1;
dfs(x,y+1);
mp[x+1][y] = 2;
mp[x][y] = 2;
dfs(x,y+1);
mp[x+1][y] = 0;
mp[x][y] = 0;
}
}
int main()
{
std::ios::sync_with_stdio(false);
cin>>n>>m;
dfs(0,0);
cout<<ans<<endl;
return 0;
}