标题:方格分割
6x6的方格,沿着格子的边线剪开成两部分。
要求这两部分的形状完全相同。
如图:p1.png, p2.png, p3.png 就是可行的分割法。
试计算:
包括这3种分法在内,一共有多少种不同的分割方法。
注意:旋转对称的属于同一种分割法。
请提交该整数,不要填写任何多余的内容或说明文字。
分析:当我们发现一道题用常规的方法很难解决时,就丢掉我们已经思考的思路,去开拓一种新的思路,寻找别的解决方案
此题如往常一样去选格子,很显然是非常难得一件事情,那我们不妨换一个思路,直接模仿剪刀的走向,为了实现两块一样的区域,我们可以用两把剪刀从中间对称的同时两个方向剪,那怎么模仿剪刀走向?还是回到DFS,怎么同时剪?,我们搜一边,同时标记对称点即可。
#include<cstdio>
int mp[7][7];
bool vis[7][7];
int vir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};//四个方向
int cnt;
void dfs(int x,int y){
if(x==0||y==0||x==6||y==6){//剪到边了
cnt++;
return ;
}
vis[x][y]=true;
vis[6-x][6-y]=true;//标记对称点
for(int i=0;i<4;i++){
int tx=x+vir[i][0];
int ty=y+vir[i][1];
if(tx>=0&&tx<7&&ty>=0&&ty<7&&!vis[tx][ty]){
dfs(tx,ty);
}
}
vis[x][y]=false;
vis[6-x][6-y]=false;
}
int main(){
dfs(3,3);//从中间点开始搜素
printf("%d\n",cnt/4);//旋转对称属于一个方法
return 0;
}
代码二:
#include<bits/stdc++.h>
using namespace std;
int mp[7][7];
int vir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
int ans;
void dfs(int x,int y,int a,int b){
if(x==0||x==6||y==0|y==6){
ans++;
return ;
}
for(int i=0;i<4;i++){
int tx=x+vir[i][0];
int ty=y+vir[i][1];
int ta=a-vir[i][0];
int tb=b-vir[i][1];
if(mp[tx][ty]!=1&&tx>=0&&tx<7&&ty>=0&&ty<7){
mp[tx][ty]=1;
mp[ta][tb]=1;
dfs(tx,ty,ta,tb);
mp[tx][ty]=0;
mp[ta][tb]=0;
} }
}
int main(){
mp[3][3]=1;
dfs(3,3,3,3);
cout<<ans/4<<endl;
return 0;
}