蓝桥杯真题之“方格分裂"_DFS深度搜索(c++实现)

上文链接:蓝桥杯真题之购物单(一分钟巧解)


方格分割

6x6的方格,沿着格子的边线剪开成两部分。
要求这两部分的形状完全相同。
如下三图就是可行的分割法。
试计算:
包括这3种分法在内,一共有多少种不同的分割方法。
注意:旋转对称的属于同一种分割法。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

我的思路

  • 方格解析:该方格是7行7列的方格,红橙两连通方格围绕(3,3)对称。图示如下。
    在这里插入图片描述
  • 思路:求解对称的方式有多少种,可以利用DFS(深度遍历)+递归思想,从中心对称点开始走,一次走到结尾。过程为:先标注当前点及对称点,然后沿着当前点向四个方向走,走前判断下步是否合法且是否已经走过,若合法,走到下步继续重复此过程(递归实现)。直到走到边界。注意点如下。
  1. 从该点走完时回溯该点未走过的状态,为下次再走做准备。
  2. 因为从对称中心(3,3)向四个方向均可以走,如果走的路径相同,那么最后结果旋转之后呈现的对称方式相同。所以最后得到的结果应该除以4。

算法展示

#include <iostream>
using namespace std;
typedef int It;//为方便大范围时修改进行类型定义 

It tag[7][7];//标注被访问的点
It dire[4][2]={{0,1},{0,-1},{-1,0},{1,0}};//定义行走方向,上下左右 
It ans=0;//记录结果,因为(x,y)向四个方向走并标注对称方格,旋转之后沿四个方向走相同步骤其实是同一种对称方式,所以结果应该除以4 
It lenDire = sizeof(dire)/sizeof(dire[0]);//获取方向长度 
 
void dfs(It x,It y)//深度遍历 
{
	if(x==0||y==0||x==6||y==6)//走到边界,表示可以构成对称方格,记录该方式。 
	{
		ans++;
		return; 
	}
	//标注走过点 
	tag[x][y]=1;
	tag[6-x][6-y]=1;
	//改变方向行走
	for(int i =0;i<lenDire;i++)
	{
		int curX = x+dire[i][0];
		int curY = y+dire[i][1];
		//判断当前走向是否合法且未走过
		if(tag[curX][curY]==1||(curX<0||curY<0||curX>6||curY>6))continue; 
		
		dfs(curX,curY);
	} 
	//查找完成后回溯标注点
	tag[x][y]=0;
	tag[6-x][6-y]=0;
}
 
int main()
{
	dfs(3,3); 
	cout<<ans/4<<endl;
	return 0;
}
发布了30 篇原创文章 · 获赞 3 · 访问量 2745

猜你喜欢

转载自blog.csdn.net/weixin_44077556/article/details/104769408
今日推荐