磁砖样式

小明家的一面装饰墙原来是 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;
}

猜你喜欢

转载自blog.csdn.net/qq_39562286/article/details/80425416
今日推荐