方格分割 java代码DFS
题目描述:
6x6的方格,沿着格子的边线剪开成两部分。要求这两部分的形状完全相同。
如图:就是可行的分割法。
试计算:包括这3种分法在内,一共有多少种不同的分割方法。注意:旋转对称的属于同一种分割法。
输出:
请提交该整数,不要填写任何多余的内容或说明文字。
分析
- 观察该图,将中心点设为(3,3),发现从(3,3)点开始走出该方格有一条路线path。
- 将path中心对称后形成path2,path和path2则将该图分为一个对称图形;
- path是从(3,3)走出,如果旋转对称是同一种的话,需要将path的数目/4
- path在走第一步的时候就会4个选择(上下左右),第二步的时候也会有4个选择(上下左右),第三步的时候也会有4个选择(上下左右),等等…;
- 但是一次只能走一步,所以需要for循环,如果第一步走了上,下一个第一步就走下,下一个第一步就走左,下一个第一步就走右,然后下一个第二步走上,等等…
- 然后需要借助一个访问地图,记录每一次完整(比如第一次全向上)走过的路,设为true,走完后,将地图重新设为false。
有个问题是为什么要对称位置也要设为true?
假如对称位置不设为true,path会怎么走呢??它可能会绕着(3,3)转着出来,这样的路径就不会形成对称图形了。
例如下图
答案:509
public class DFS_2 {
static int[] X = { 0, -1, 1, 0, 0 };//向左向右,
static int[] Y = { 0, 0, 0, -1, 1 };//向上向下,
static int count = 0;//统计次数
static boolean[][] vis = new boolean[10][10];//访问地图
public static void main(String[] args) {
// TODO Auto-generated method stub
vis[3][3]=true;
dfs(3, 3);
System.out.println(count/4);//
}
static void dfs(int i, int j) {
if (i == 0 || i== 6 || j == 0 || j == 6) {//到达了出口处
count++;
return;//结束
}
for (int l = 1; l <= 4; l++) {
//l=1的时候,(3,3)向左移动一步,从l=1到l=4,(3,3)上下左右都将会移动一步;
//由于利用了递归,所以下一个的dfs()也会上下左右都移动;
i += X[l];//左右
j += Y[l];//上下
if (!vis[i][j]) {//如果该点未访问过
vis[i][j] = true;
vis[6 - i][6 - j] = true;//对称位置
dfs(i, j);//走下一步;
vis[i][j] = false;//访问后,再将该点设为未访问,为另一条新路径做准备
vis[6 - i][6 - j] = false;
}
i -= X[l];//如果该点访问过,i就进行回退,然后进入下个循环,走新的一步
j -= Y[l];//如果该点访问过,j就进行回退,然后进入下个循环,走新的一步
}
}
}