标题:方格分割

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

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

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

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

 

观察可得他是一个中心对称图形,我们只需要搜索它的对称线即可。我们可以把对称线抽象为从(4,4)出发到达(1,y),或(7,y),或(x,1),或(x,7)的路径。易知这条路径只是对称线的一半,因为另一半与这条路径关于(4,4)对称。所以我们只需要注意这条路径不能和它的关于(4,4)对称的另一半路径相交就行了。

例如


该条路线从 (4,4)->(4,3)->(5,3)->(5,2)->(4,2)->(3,2)->(3,3)->(2,3)->(2,2)->(1,2)。

在搜索的过程,我们不仅要标记它走过的点,而且还要标记该点关于中心点(4,4)对称的点。

因为我们不仅要满足该条路径的每个点只走一次,而且还要满足该条路径不能和它的关于(4,4)对称的另一半路径相交。

代码如下

#include<stdio.h>
const int INF = 8;     //地图范围为1~7; 

int mark [INF][INF] = {0}, dir[4][2] = {1,0,0,1,-1,0,0,-1};

int CenterPointX = INF/2, CenterPointY = INF/2, result = 0;

void dfs(int x,int y);

int main()
{
	mark[CenterPointX][CenterPointY] = 1;
	
	dfs(CenterPointX,CenterPointY);
	
	printf("%d\n",result/4);    	//旋转对称属于同一种。所以要除以4 
	
	
	return 0;
}

void dfs(int x,int y)
{
	if(x == 1 || x == INF-1 || y == 1 || y == INF-1)
	{
		result++;
		
		return ;
	}
	else
	{
		for(int i=0; i < 4; i++)
		{
			int nx = x + dir[i][0];
			
			int ny = y + dir[i][1];
			
			if(nx >= 1 && ny <= INF-1 && ny >= 1 && ny <= INF-1 && mark[nx][ny] == 0)
			{
				/*
				点(x,y)关于(m,n)的对称点为(2*m-x,2*n-y) ;
				*/
				mark[nx][ny] = 1;	//标记已走过的点 
				
				mark[2 * CenterPointX - nx][2 * CenterPointY - ny] = 1;  	//标记该点关于中心点对称的点
				
				dfs(nx,ny) ;
				
				mark[nx][ny] = 0;
				
				mark[2 * CenterPointX - nx][2 * CenterPointY - ny] = 0;
			}
			
		}
	}
	
	
	
}