标题:方格分割6x6的方格,沿着格子的边线剪开成两部分。
要求这两部分的形状完全相同。如图:p1.png, p2.png, p3.png 就是可行的分割法。
![]()
p1.png ![]()
p2.png ![]()
p3.png 试计算:
包括这3种分法在内,一共有多少种不同的分割方法。
注意:旋转对称的属于同一种分割法。请提交该整数,不要填写任何多余的内容或说明文字。
509
这道题可以使用dfs求解,将方格分割成2个对称且连接的部分,相当于我们需要找到一个连接线,即找到连接线条之间的点。6X6的方格中有7X7个顶点,我们只需要从这7个顶点中找到符合要求的点进行划分即可,中心点肯定需要在其中,因此我们从中心点开始,然后依次向4个方向进行扩张;由于对称性,每次需要按照对称的方式扩张2个点。最后考虑到旋转相同的问题,需要将找到的结果除以4,即得到最终的结果。题目要求沿着格子的边线剪成两个部分,仔细观察,剪开的边线是关于中心点(3,3)对称的,于是我们从(3,3)开始搜索,直到搜到边界则退出。需要注意的是要从(3,3)点开始向两个方向同时搜索,并且这里两个方向是相反的。最后得出的结果要除以4,因为旋转堆成的属于同一种分割法。
#include <iostream>
#include <cstring>
using namespace std;
char map[7][7];
int vis[7][7];//使用bool型,不能用memset(vis,0,sizeof(vsi))初始化
int dir[4][2] = {-1,0,1,0,0,-1,0,1};
int count = 0;
void dfs(int x, int y)
{
if(vis[x][y] == 1)
return;
if(x == 0 || x == 6 || y == 0 || y == 6)
{
count++;
return;
}
vis[x][y] = 1;
vis[6-x][6-y] = 1;
for(int i = 0; i < 4; i++)
{
int tx = x + dir[i][0];
int ty = y + dir[i][1];
if(tx >= 0 && tx <= 6 && ty >= 0 && ty <= 6)
dfs(tx,ty);
}
vis[x][y] = 0;
vis[6-x][6-y] = 0;
}
int main(int argc, char** argv) {
dfs(3,3);
cout<<count/4<<endl;
return 0;
}
#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
bool book[7][7];
int dir[4][2] = {-1,0,1,0,0,-1,0,1};
int N = 6;
int sum = 0;
void dfs( int r, int c )
{
if( r==0 || r==N || c==0 || c==N )
{
sum++;
return;
}
int tmpr,tmpc;
for(int i=0;i<4;i++)
{
tmpr = r + dir[i][0];
tmpc = c + dir[i][1];
if( tmpr>N || tmpr<0 || tmpc>N || tmpc<0 )
continue;
if( !book[tmpr][tmpc] )
{
book[tmpr][tmpc] = true;
book[N-tmpr][N-tmpc] = true;
dfs( tmpr, tmpc );
book[tmpr][tmpc] = false;
book[N-tmpr][N-tmpc] = false;
}
}
}
int main(int argc, char** argv) {
book[N/2][N/2] = true;
dfs( N/2, N/2 );
printf("%d\n", sum/4);
return 0;
}