Blue Bridge Cup true problem of "split box" _DFS depth of the search (c ++ to achieve)

Link above: the Blue Bridge Cup Exams, the shopping list (one minute Solving)


Grid division

6x6 squares, cut into two parts along the edge of the grid.
It requires the same shape of the two parts.
FIG following three division method is feasible.
Calculate:
include these three points, including the law, a number of different segmentation total.
Note: a rotationally symmetrical belong to the same division method.
Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description

My thoughts

  • Analytical squares: squares is the square of 7 rows 7, two red-orange squares surrounding communication (3,3) symmetry. Illustrated as follows.
    Here Insert Picture Description
  • Thinking: How many solving symmetrical manner, you can use DFS (depth traversal) + recursive thinking, began to walk from the center point of symmetry, once went to the end. Process: first mark the current point and point symmetry, then go to the four directions along the current point, take the next step to determine whether the former has gone through legitimate and whether, if legitimate, go to the next step to continue to repeat the process (recursive) . Until walked border. Note the following points.
  1. The point is not backtrack through the state from the finish point, in preparation for the next walk.
  2. Because both can walk from the center of symmetry (3,3) to the four directions, the same as if walking path, the same symmetry presented after the final result of the rotation. So the final result should be divided by four.

Algorithm show

#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;
}
Published 30 original articles · won praise 3 · Views 2745

Guess you like

Origin blog.csdn.net/weixin_44077556/article/details/104769408