小明家的一面装饰墙原来是 3*10 的小方格。
现在手头有一批刚好能盖住2个小方格的长方形瓷砖。
瓷砖只有两种颜色:黄色和橙色。
小明想知道,对于这么简 陋的原料,可以贴出多少种不同的花样来。
小明有个小小的强迫症:忍受不了任何2*2的小格子是同一种颜色。
(瓷砖不能切割,不能重叠,也不能只铺一部分。另外,只考虑组合图案,请忽略瓷砖的拼缝)
显然,对于 2*3 个小格子来说,口算都可以知道:一共10种贴法,如【p1.png所示】
但对于 3*10 的格子呢?肯定是个不小的数目,请你利用计算机的威力算出该数字。
注意:你需要提交的是一个整数,不要填写任何多余的内容(比如:说明性文字)
答案:101466
先按照正常情况进行,如果铺满了就进行检查,检查完如果符合条件,再把数组转成string放入到set里面去,进行去重
#include<iostream>
#include<set>
using namespace std;
const int n = 5;
const int m = 12;
int a[n][m];
long long sum = 0;
set<string> se;
void dfs(int count);//count代表现在铺了几块瓷砖了
bool check();
int main()
{
dfs(0);
cout<<sum<<endl;//105760
cout<<se.size()<<endl;//101466 查重之后
return 0;
}
void dfs(int count)
{
if(count == 30){
if(check()){
string s = "";
char b [30];
int k = 0;
for(int i=1;i<=n-2;i++){
for(int j=1;j<=m-2;j++){
b[k++] = 'a'+ (a[i][j]);
}
}
s += b;// 将数组转换成字符串
se.insert(s);//查重
sum ++;
}
return ;
}
for(int i=1;i<=n-2;i++){
for(int j=1;j<=m-2;j++){
//横着
if(a[i][j] == 0){
if(j<m-2 && a[i][j+1]==0){
a[i][j] = 1;//橙色
a[i][j+1] = 1;
dfs(count +2);
a[i][j] =2;//黄色
a[i][j+1] = 2;
dfs(count +2);
a[i][j] = 0;
a[i][j+1] = 0;
}
//竖着
if(i<n-2 && a[i+1][j]==0){
a[i][j] = 1;//橙色
a[i+1][j] =1;
dfs(count+2);
a[i][j] = 2;//黄色
a[i+1][j] = 2;
dfs(count+2);
a[i][j] = 0;
a[i+1][j] = 0;
}
return ;
}
}
}
return ;
}
bool check()
{
for(int i=1;i<n-2;i++){
for(int j=1;j<m-2;j++){
if((a[i][j] + a[i][j+1] +a[i+1][j]+a[i+1][j+1])%4==0){//如果四个都一样,那么就代表重复了
return false;
}
}
}
return true;
}