方格分割
6x6的方格,沿着格子的边线剪开成两部分。
要求这两部分的形状完全相同。
如图:1,2,3 就是可行的分割法。
试计算:
包括这3种分法在内,一共有多少种不同的分割方法。
注意:旋转对称的属于同一种分割法。
请提交该整数,不要填写任何多余的内容或说明文字。
图1:
图2:
图3:
注意: dfs搜块的话形如图3的就不行了,因为dfs是一下画到底所以搜块不对!
error code(搜块):
#include<stdio.h>
#include<string.h>
using namespace std;
int dir[4][2]={
{
0,1},{
1,0},{
0,-1},{
-1,0}};
int M[7][7];
int ans=0;
bool ok(){
for(int i=1;i<=6;i++){
for(int j=1;j<=3;j++){
if(M[i][j]==M[6-i+1][6-j+1])return false;
}
}
return true;
}
void dfs(int x,int y,int num){
M[x][y]=1;
if(num>18)return ;
else if(num==18){
if(ok()){
ans++;
}
return ;
}else{
for(int i=0;i<4;i++){
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(xx>=1&&xx<=6&&yy>=1&&yy<=6&&M[xx][yy]==0){
dfs(xx,yy,num+1);
M[xx][yy]=0;
}
}
}
}
int main(){
memset(M,0,sizeof M);
dfs(1,1,1);
printf("%d",ans/4);
return 0;
}
正确思路:
应该搜边,从中心(3,3)向边界搜索,设置两个对称方向,只要是走到边界ans++;
由于旋转对称属于一种,而自己用的是双边法,所以最后ans/2即可!
correct code:(搜边):
#include<stdio.h>
#include<string.h>
using namespace std;
int dir[4][2]={
{
0,1},{
1,0},{
0,-1},{
-1,0}};
int M[7][7];
int ans=0;
void dfs(int x,int y){
M[x][y]=1;
M[6-x][6-y]=1;
if(x==0||y==0||x==6||y==6){
ans++;
return ;
}else{
for(int i=0;i<4;i++){
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(xx>=1&&xx<=6&&yy>=1&&yy<=6&&M[xx][yy]==0&&M[6-xx][6-yy]==0){
dfs(xx,yy);
M[xx][yy]=0;
M[6-xx][6-yy]=0;
}
}
}
}
int main(){
memset(M,0,sizeof M);
dfs(3,3);
printf("%d",ans/2);
return 0;
}