欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

蓝桥杯 2017第八届国赛c/c++b组第2题 磁砖样式

程序员文章站 2024-02-10 16:08:52
...

/*

标题:磁砖样式

小明家的一面装饰墙原来是 3*10 的小方格。
现在手头有一批刚好能盖住2个小方格的长方形瓷砖。
瓷砖只有两种颜色:黄色和橙色。

小明想知道,对于这么简陋的原料,可以贴出多少种不同的花样来。
小明有个小小的强迫症:忍受不了任何22的小格子是同一种颜色。
(瓷砖不能切割,不能重叠,也不能只铺一部分。另外,只考虑组合图案,请忽略瓷砖的拼缝)
显然,对于 2
3 个小格子来说,口算都可以知道:一共10种贴法,如【p1.png所示】

但对于 3*10 的格子呢?肯定是个不小的数目,请你利用计算机的威力算出该数字。

注意:你需要提交的是一个整数,不要填写任何多余的内容(比如:说明性文字)
蓝桥杯 2017第八届国赛c/c++b组第2题 磁砖样式
分析:
从第一行第一列开始贴,
如果贴过了递归到该行下一列
如果越界了递归到下一行第一列
有四种可能:横着贴黄色或橙色;竖着贴黄色和橙色,题目里用0和1表示
贴完后(递归边界):
1.判断2*2的小格子是否是同一种颜色
2.检查是否重复
3.ans++
*/

#include<iostream>
#include<map>
#include<cstring>
using namespace std;
typedef long long int ll;
int a[5][12],n,m,ans;
map<ll,ll>check;
bool judge()	//judge:判断2*2的小格子是否是同一种颜色 
{
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
	if(a[i][j]==a[i][j+1]&&a[i][j]==a[i+1][j]&&a[i][j]==a[i+1][j+1])
	return false;
	}
	return true;
}
bool check_()	//判断有没有重复 
{
	int s=0,bit=1;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
		{
			s+=a[i][j]*bit;
			bit*=2;
		}
	if(check[s]==0)
		{
			check[s]=1;
			return true;
		}
		return false;
} 
void dfs(int x,int y)
{
	if(x==n+1)
	{
	if(judge()&&check_())
	{
		ans++;
	}
	return; 
	}
	if(a[x][y]==-1)	//判断该位置是否贴过瓷砖,贴过了y+1 
	{
	if(y<m+1)	//判断该位置是否越界,越界了dfs(x+1,1)
	{
		if(y<m&&a[x][y+1]==-1)//横着放1或0
		{
		a[x][y]=a[x][y+1]=1;
		dfs(x,y+2);
		a[x][y]=a[x][y+1]=0;
		dfs(x,y+2);
		a[x][y]=a[x][y+1]=-1;
		}
		if(x<n&&a[x+1][y]==-1)//竖着放1或0
		{
		a[x][y]=a[x+1][y]=1;
		dfs(x,y+1); 
		a[x][y]=a[x+1][y]=0; 
		dfs(x,y+1); 
		a[x][y]=a[x+1][y]=-1;
		}
	}
	else
	dfs(x+1,1);
	}
	else
	dfs(x,y+1);
	
}
int main()
{
	cin>>n>>m; 
	memset(a,-1,sizeof(a));
	dfs(1,1);
	cout<<ans<<endl;
//	cout<<check.size()<<endl;
	return 0; 
}

上一篇: 使用和学习PHP有多难

下一篇: