题目描述
6x6的方格,沿着格子的边线剪开成两部分。要求这两部分的形状完全相同。
试计算:包括这3种分法在内,一共有多少种不同的分割方法。注意:旋转对称的属于同一种分割法。
java代码
遇到该种格子题目,我们总是会想到二维数组,并用每一个元素代表一个格子。
但是既然是剪格子,我们应该注意的其实是剪刀的路径,而不是格子。
这里我们用二维数组代表上图中格子间的点,令最左下角的点为[0,0]。
显然,要使剪出来的图形是对称的,剪刀必须经过[3,3]代表的点。
那么以[3,3]的点作为起点,剪刀剪到边的时候,会有以[3,3]为中心对称的另一条线,这样就将这36个格子分成了两个中心对称、可以用剪子剪出来的图形。
显然,最后要将所有的结果除以4才是本题答案。举一个简单的例子,就是剪刀朝上、下、左、右四个方向剪到底,那么显然为4种重复得剪法。
public class Main {
static int ans = 0;
static int[][] dire = { { 0, 1 }, { 0, -1 }, { -1, 0 }, { 1, 0 } };
static boolean[][] vis = new boolean[7][7];
public static void main(String[] args) {
dfs(3, 3);
System.out.println(ans / 4);
}
private static void dfs(int x, int y) {
// 如果剪刀的落点处在格子边缘,显然是一种剪法
if (x == 0 || y == 0 || x == 6 || y == 6) {
ans++;
return;
}
// 标记当前点以及与其对称的点为true,标明剪刀已经经过该点,防止重复剪
vis[x][y] = true;
vis[6 - x][6 - y] = true;
// 深度优先搜索,可以向上下左右四个方向处理
for (int i = 0; i < dire.length; i++) {
int tx = x + dire[i][0];
int ty = y + dire[i][1];
// 如果移动之后的点为false,那么就去处理该点
if (!vis[tx][ty]) {
dfs(tx, ty);
}
}
// 回溯
vis[x][y] = false;
vis[6 - x][6 - y] = false;
}
}