标题:方格分割
6x6的方格,沿着格子的边线剪开成两部分。
要求这两部分的形状完全相同。
如图:p1.png, p2.png, p3.png 就是可行的分割法。
试计算:
包括这3种分法在内,一共有多少种不同的分割方法。
注意:旋转对称的属于同一种分割法。
请提交该整数,不要填写任何多余的内容或说明文字。
答案:509
解题思路:仔细样例,我们可能会掉入暴力填充格子的坑中,仔细看我们切割格子的现时关于中心点(3,3)对称的。那么我们可以将格子格子之间接壤的看作边,边与边相交的看作点。则从(3,3)点出发,找一条边到达图案的外圈的路,不过值得注意的是,从(3,3)出发的是看错两个人出发,两个人的线路一直是对称。所以dfs中标记的时候要一步标记两个。最后的结果要除以4,因为题目中说要旋转对称的是同一种。
#include <iostream>
using namespace std;
int ans;//用来计数
//四个方向
int dire[][2] = {{-1,0},
{1,0},
{0,-1},
{0,1}};
int vis[7][7];//此数组用来记线段
void dfs(int x,int y)
{
if(x==0||y==0||x==6||y==6)//搜索到边缘
{
ans++;
return;
}
vis[x][y] = 1;//当前的点标注为以访问
vis[6-x][6-y] = 1;//对称点也标注为以访问
for(int k = 0;k<4;++k)//完成对四个方向的遍历 :下、上、右、左
{
int nx = x + dire[k][0];
int ny = y + dire[k][1];
//(nx,ny)新坐标
if(nx<0||nx>6||ny<0||ny>6) continue;//必不可少
if(!vis[nx][ny])//未被访问过
{
dfs(nx,ny);//递归
}
}
//重中之重:回溯
vis[x][y] = 0;
vis[6-x][6-y] = 0;//对称
}
int main()
{
dfs(3,3);
cout<<ans/4<<endl;
return 0;
}