蓝桥杯真题之“方格分裂"_DFS深度搜索(c++实现)
作者:互联网
上文链接:蓝桥杯真题之购物单(一分钟巧解)
方格分割
6x6的方格,沿着格子的边线剪开成两部分。
要求这两部分的形状完全相同。
如下三图就是可行的分割法。
试计算:
包括这3种分法在内,一共有多少种不同的分割方法。
注意:旋转对称的属于同一种分割法。
我的思路
- 方格解析:该方格是7行7列的方格,红橙两连通方格围绕(3,3)对称。图示如下。
- 思路:求解对称的方式有多少种,可以利用DFS(深度遍历)+递归思想,从中心对称点开始走,一次走到结尾。过程为:先标注当前点及对称点,然后沿着当前点向四个方向走,走前判断下步是否合法且是否已经走过,若合法,走到下步继续重复此过程(递归实现)。直到走到边界。注意点如下。
- 从该点走完时回溯该点未走过的状态,为下次再走做准备。
- 因为从对称中心(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;
}
标签:dfs,真题,c++,蓝桥,tag,方格,dire,对称,标注 来源: https://blog.csdn.net/weixin_44077556/article/details/104769408