方格分割 java代码DFS

方格分割 java代码DFS

题目描述:
6x6的方格,沿着格子的边线剪开成两部分。要求这两部分的形状完全相同。

如图:就是可行的分割法。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

试计算:包括这3种分法在内,一共有多少种不同的分割方法。注意:旋转对称的属于同一种分割法。
输出:

请提交该整数,不要填写任何多余的内容或说明文字

分析

  1. 观察该图,将中心点设为(3,3),发现从(3,3)点开始走出该方格有一条路线path。
  2. 将path中心对称后形成path2,path和path2则将该图分为一个对称图形;
  3. path是从(3,3)走出,如果旋转对称是同一种的话,需要将path的数目/4
  4. path在走第一步的时候就会4个选择(上下左右),第二步的时候也会有4个选择(上下左右),第三步的时候也会有4个选择(上下左右),等等…;
  5. 但是一次只能走一步,所以需要for循环,如果第一步走了,下一个第一步就走,下一个第一步就走,下一个第一步就走,然后下一个第二步走上,等等…
  6. 然后需要借助一个访问地图,记录每一次完整(比如第一次全向上)走过的路,设为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就进行回退,然后进入下个循环,走新的一步
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山海上的风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值