-
题目描述
6x6的方格,沿着格子的边线剪开成两部分。
要求这两部分的形状完全相同。
如图:p1.png, p2.png, p3.png 就是可行的分割法
-
试计算:
包括这3种分法在内,一共有多少种不同的分割方法。
注意:旋转对称的属于同一种分割法。
请提交该整数,不要填写任何多余的内容或说明文字。 -
我的想法(因为之前写过一遍所以有点印象)
从最中间的那个点(3,3)开始dfs,按照两种相反的走法走,当走到边界时,这两条路线合在一起将方格分割成两部分
#include <iostream>
#include<string.h>
using namespace std;
int cnt;
bool vis[7][7];
int dir1[4][2]={-1,0,1,0,0,-1,0,1};
int dir2[4][2]={1,0,-1,0,0,1,0,-1};//第二条路的走法和第一条相反
bool check(int a,int b,int c,int d){//确保两个点都到了边界
int flag1=0,flag2=0;
if(a==0||a==6||b==0||b==6) flag1=1;
if(c==0||c==6||d==0||d==6) flag2=1;
if((a+c==6)&&(b+d==6)&&flag1&&flag2) return true;
else return false;
}
void dfs(int a,int b,int c,int d){
if(check(a,b,c,d)){
cnt++;
return;
}
for(int i=0;i<4;++i){
int da=a+dir1[i][0];
int db=b+dir1[i][1];
int dc=c+dir2[i][0];
int dd=d+dir2[i][1];
if(da<0||da>6||db<0||db>6||dc<0||dc>6||dd<0||dd>6||vis[da][db]||vis[dc][dd]){
continue;
}
vis[da][db]=true;vis[dc][dd]=true;
dfs(da,db,dc,dd);
vis[da][db]=false;vis[dc][dd]=false;
}
}
int main()
{
cnt=0;
memset(vis,false,sizeof(vis));
vis[3][3]=true;
dfs(3,3,3,3);
cout<<cnt/4<<endl;
return 0;
}
- 还有更简洁的写法
可以发现第二条路线是与第一条路线相反的方向走的,那达到的点其实与第一条线到达的点是关于(3,3)对称的,比如点(3,2)和(3,4)可以发现它们的横纵坐标和为6,那dfs就可以不需要4个参数了,两个就好,即只需要知道一条路的走法就好了,且当一条路走到了边界,那另一条路也必定到了边界,因为它们的对称关系
#include<iostream>
using namespace std;
int vis[10][10] = {0};
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
int ans = 0;
void DFS(int x,int y)
{
if(!x || !y || x==6 || y==6)//判断到边界了
{
ans++;
return ;
}
for(int i = 0; i < 4; i++)
{
int tempx = x + dir[i][0];
int tempy = y + dir[i][1];
if(!vis[tempx][tempy])//这里不用判断超没超边界,必不可能超
//假设超了边界那tempx,tempy应该是由边界点走出来的,也就是x,y是边界点
//但是如果x,y是边界点,在上面的if中就return掉了,所以不可能
{
vis[tempx][tempy] = 1;
vis[6-tempx][6 - tempy] = 1;//对称点
DFS(tempx,tempy);
//这里为什么要复原?可以看下面的图
vis[tempx][tempy] = 0;
vis[6-tempx][6 - tempy] = 0;
}
}
}
int main()
{
vis[3][3] = 1;
DFS(3,3);
cout << ans/4 <<endl;//为什么除以4?
//因为ans把所有走法都算了,但是题目说了旋转对称的属于同一种分割法
//而一种走法按旋转不同来算就有四种走法
return 0;
}
黑点可以通过绿线的走法走到,也可以通过蓝线的走法走到,假设先按绿线走,那走完后黑点的vis为真,然后进一步dfs下一步走法
但是在dfs完绿线方案后必须将黑点的vis置为false,因为蓝线的走法也有可能得到答案,它也要能走黑点