「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战」。
这道题的难度定义为中等难度,是一道深度优先搜索的题目。如果知道正确运用深度优先搜索来解,这道题是不难的,只是如何想到去用,这里是一个难点。
题目
给定一个6x6的方格,沿格子线进行切割,最后结果要求切割出的两部分完全相同。 要求求出一共有多少种不同的切割方法。
旋转对称属于同一种切法。
如图,这是一个切法。
思路
要切出一模一样的部分,我们应该怎么去切?我们可以想象有一根连续的线,这根线是可以上下左右移动的,然后有另一根一样的线,从一个起点开始,这根线往上走,另一根线就往下走,始终走与这根线相反的方向。这一根线走到边界时,另一根线也走到了边界。这个时候,整个方格就被分成了两部分。这个时候,这两部分一定是一样的。知道如何去分割,接下来我们就可以设计程序了。设一个二维数组,6x6的方格一共有36个点,我们从最中间的点(3,3),开始,往上下左右四个方向开始走,还有另一根线往相反的方向切割。到达边界时我们就可以将切割的方法加一了。但是这样得到的总切割方法数不是正确的,往上下左右四个方向走,跟另一个方向的走法会有一次重复,所以我们需要将结果除以2,但是旋转对称是属于同一种切法的,我们还需要将结果除以2。加起来就是一共除以4得到最终答案。
代码
#include<bits/stdc++.h>
using namespace std;
int vis[7][7];//算上边界一共49个点
int turn[4][2]={0,1,0,-1,1,0,-1,0};//模拟四个方向
int ans;
void dfs(int x,int y){
if(x==0||y==0||x==6||y==6){
ans++;
return;
}
int x1,y1,x2,y2;
for(int i=0;i<4;i++){
x1=x+turn[i][0];
y1=y+turn[i][1];
x2=6-x1;
y2=6-y1;
if(!vis[x1][y1]){
vis[x1][y1] = vis[x2][y2] = 1;
dfs(x1,y1);
vis[x1][y1] = vis[x2][y2] = 0;
}
}
}
int main(){
memset(vis, 0, sizeof(vis));
vis[3][3] = 1;
dfs(3,3);
cout<<ans/4;
return 0;
}