第八届蓝桥杯个人赛省赛(软件类)C++B组试题第四题

一【题目描述】


标题:方格分割

6x6的方格,沿着格子的边线剪开成两部分。
要求这两部分的形状完全相同。

如图:p1.png, p2.png, p3.png 就是可行的分割法。

试计算:
包括这3种分法在内,一共有多少种不同的分割方法。
注意:旋转对称的属于同一种分割法。

请提交该整数,不要填写任何多余的内容或说明文字。

 

二【解题思路】

     首先看到题目是分割,就想到了用dfs或者生成法,但是生成法最后进行判断很难实现,就用dfs吧。那么从哪里开始搜索呢?我们首先要定义一个二维的数组,然后在里面进行判断,如果从(0,0)开始,我们就不好考虑对称的那一块怎么去求解。所以既然是中心对称,那么就从重点(3,3)开始去搜索,然后对应点另一个面就是对应坐标对称,例如走到了(x,y),那么对称的那一个就要考虑到(6-x,6-y),在考虑到判断的条件。然后我们的搜索其实是有4块一样的,所以最后得到的结果再除以4,就得到了最后的结果。那么开始码代码吧。

     

三【解题步骤】

#include<iostream>
using namespace std;
int dire[][2]={{-1,0},{1,0},{0,-1},{0,1}};//dfs习惯,先定义方向数组,左、右、上、下。
int vis[7][7];//定义数组
int ans=0;
void dfs(int x,int y)//dfs深搜
{
	if(x==0||y==0||x==6||y==6)//退出的条件,到边界了就结束,那么结果加一
	{
		ans++;
		return;
	}
	vis[x][y]=1;//标记此处走过了
	vis[6-x][6-y]=1;//对称的点也标记
	for(int i=0;i<4;i++)//进行四个方向搜索
	{
		int nx = x+dire[i][0];//横坐标
		int ny = y+dire[i][1];//纵坐标,这个是根据自己定义的方向数组来的
		if(nx<0||nx>6||ny<0||ny>6) continue;//如果下一个点越界了,不走
		if(!vis[nx][ny])//继续dfs没有走过的点
		{
			dfs(nx,ny);	
		} 
		 
	}
	vis[x][y]=0;//回溯,把走过的点再次标记未走过,下次在进行判断。
	vis[6-x][6-y]=0;
	
}
int main()
{
	dfs(3,3);
	cout<<ans/4<<endl;//相当于旋转搜索,所以重复了4重,最后的结果除以四
}

答案是:509

四【总结】

     题目做完你会发现其这里的分割我们就是对数组进行处理,然后利用基本的dfs进行操作。如有误,请指出,谢谢!

发布了123 篇原创文章 · 获赞 234 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_43919400/article/details/105244928