方格分割
本题总分:17分
6x6的方格,沿着格子的边线剪开成两部分。
要求这两部分的形状完全相同。如图:p1.png, p2.png, p3.png 就是可行的分割法。
![]()
![]()
试计算:
包括这3种分法在内,一共有多少种不同的分割方法。
注意:旋转对称的属于同一种分割法。请提交该整数,不要填写任何多余的内容或说明文字。
正常思维的话,深搜整张图,找出18个涂色的块,然后判断是否对称。但是36个块里搜18个,复杂度太高,有限的时间内是跑不出来的。
这题的正确解法是搜索切割线。
因为图形是中心对称的,所以应该以中心点为起点,向四周搜索。
同时,每搜到一个点,标记这个点对称的点。
每次搜到边界,说明找到了一条切割线。
最后结果要除以4,一张图可以旋转4次,而旋转属于一种情况。
不需要管对称,因为搜索的是切割线,每条切割线包含两种对称情况,比如:
#include <iostream>
#include <cstring>
using namespace std;
int book[10][10];
int dire[4][2] = {-1, 0, 1, 0, 0, -1, 0, 1};
int ans;
void dfs(int x, int y)
{
if (x == 0 || y == 6 || x == 6 || y == 0)
{
/*for (int i = 0; i <= 6; i++) //输出切割线
for (int j = 0; j <= 6; j++)
cout << (book[i][j] ? '#' : '0') << (j == 6 ? '\n' : ' ');
cout << endl
<< endl;*/
ans++;
return;
}
for (int i = 0; i < 4; i++)
{
int nx = x + dire[i][0];
int ny = y + dire[i][1];
if (nx < 0 || nx > 6 || y < 0 || ny > 6)
continue;
if (!book[nx][ny])
{
book[nx][ny] = 1;
book[6 - nx][6 - ny] = 1;
dfs(nx, ny);
book[nx][ny] = 0;
book[6 - nx][6 - ny] = 0;
}
}
}
int main()
{
book[3][3] = 1;
dfs(3, 3);
cout << ans / 4 << endl;
return 0;
}
备注:
如果我们 把切割线 输出出来,
这是比较明显的情况:
![](https://i-blog.csdnimg.cn/blog_migrate/539301ecb3cb227a23e24abff467700f.png)
但是,有时候会输出下面这样的切割线,这是正常的。
![](https://i-blog.csdnimg.cn/blog_migrate/897a1ac7707b1a80f59df42fc042092d.png)
因为中心点到边缘搜索的过程中,除了切割线外,
难免走一些切割线以外的点,不可能每次都一条线搜到边缘(如图1)。
但是每次搜到边缘,都代表搜到一条切割线,这个是毋庸置疑的。
~~~~~如果有的地方 没有说清楚,欢迎大家留言~~~~~。