DFS 迷宫问题和优化 java代码

DFS迷宫问题和优化 java

X星球的一处迷宫游乐场建在某个小山坡上。 它是由10x10相互连通的小房间组成的。房间的地板上写着一个很大的字母。 我们假设玩家是面朝上坡的方向站立,则: L表示走到左边的房间, R表示走到右边的房间,U表示走到上坡方向的房间, D表示走到下坡方向的房间。
X星球的居民有点懒,不愿意费力思考在这里插入代码片。 他们更喜欢玩运气类的游戏。这个游戏也是如此!开始的时候,直升机把100名玩家放入一个个小房间内。 玩家一定要按照地上的字母移动。

UDDLUULRUL
UURLLLRRRU
RRUURLDLRD
RUDDDDUUUU
URUDLLRRUU
DURLRLDLRL
ULLURLLRDU
RDLULLRDDD
UUDDUDUDLL
ULRDLUURRR

答案
31

分析

  • 从第一个点U开始按照字母走,设一个10x10的数组,每当数组下标越界,代表走出去
  • 然后进行下个点的进入。根据UDLR进行 行列坐标的移动。

另一种方法直接数

在写的时候发现两个小问题
1.java不能直接输入字符型;
2.java的Arrays.fill()方法只能对一维数组赋值;

解决

对二维数组赋值

import java.util.Arrays;
import java.util.Scanner;

public class DFS_1 {
	static char[][] map = new char[11][11];//存储迷宫
	static boolean[][] vis = new boolean[12][12];//存储是否访问
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner input = new Scanner(System.in);
		String a;
		int ans = 0;
		for (int i = 0; i < 10; i++) {
			a = input.next();//由于java没有输入字符型,先输入一行
			map[i] = a.toCharArray();//将该行转换为字符型
		}
		for (int i = 0; i < 10; i++) {//对每个点判断能否走出
			for (int j = 0; j < 10; j++) {
				for (int m= 0; m < 10; m++) {//搜点前,每次将二位数组vis全设为FALSE
					Arrays.fill(vis[m], false);//该方法只能将一维数组设为False
				}					
				if (dfs(i, j)) {
					ans++;
				}
			}
		}
		System.out.println(ans);
	}
	private static boolean dfs(int i, int j) {
		if (i>9||i < 0 || j > 9||j<0)//出来后返回true
			return true;

		if (vis[i][j]) {//如果访问过,代表又开始访问,就认为,它在兜圈子;返回false;
			return false;
		}
		vis[i][j] = true;//访问中。。。
		if (map[i][j] == 'U') {//上
			return dfs(i - 1, j);
		}
		if (map[i][j] == 'D') {//下
			return dfs(i + 1, j);
		}
		if (map[i][j] == 'R') {//右
			return dfs(i, j + 1);
		}
		if (map[i][j] == 'L') {//左
			return dfs(i, j - 1);
		}
		return false;
	}
}

增加了一个memory数组记录已经走过的点,如果该点能出去设为1,不能出去设为2,避免一个路径与好几个路径重合,进行重复访问

import java.util.Arrays;
import java.util.Scanner;

public class DFS_1的优化 {

	static char[][] map = new char[11][11];// 存储迷宫
	static boolean[][] vis = new boolean[12][12];// 存储是否访问
	static int count;
	static int[][] memory = new int[11][11];
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner input = new Scanner(System.in);
		String a;
		int ans = 0;
		for (int i = 0; i < 10; i++) {
			a = input.next();// 由于java没有输入字符型,先输入一行
			map[i] = a.toCharArray();// 将该行转换为字符型
		}
		for (int i = 0; i < 10; i++) {// 对每个点判断能否走出
			for (int j = 0; j < 10; j++) {
				for (int m = 0; m < 10; m++) {// 搜点前,每次将二位数组vis全设为FALSE
					Arrays.fill(vis[m], false);// 该方法只能将一维数组设为False
				}
				if (dfs(i, j)) {
					ans++;
				}
			}
		}
		System.out.println(ans);
		System.out.println(count);
	}

	private static boolean dfs(int i, int j) {
		count++;
		if (i > 9 || i < 0 || j > 9 || j < 0)// 出来后返回true
		{
			return true;
		}
		
		if (vis[i][j]) {// 如果访问过,代表又开始访问,就认为,它在兜圈子;返回false;
			return false;
		}
		if (memory[i][j] == 1) {//如果该点能出去设为1,不能出去设为2
			return true;
		}
		if (memory[i][j] == 2) {
			return false;
		}
		vis[i][j] = true;// 访问中。。。

		if (map[i][j] == 'U') {// 上
			if (dfs(i - 1, j)) {
				memory[i][j] = 1;
				return true;
			} else {
				memory[i][j] = 2;
				return false;
			}
		}
		if (map[i][j] == 'D') {// 下
			if (dfs(i +1, j)) {
				memory[i][j] = 1;
				return true;
			} else {
				memory[i][j] = 2;
				return false;
			}
		}
		if (map[i][j] == 'R') {// 右
			if (dfs(i  , j+1)) {
				memory[i][j] = 1;
				return true;
			} else {
				memory[i][j] = 2;
				return false;
			}
		}
		if (map[i][j] == 'L') {// 左
			if (dfs(i, j-1)) {
				memory[i][j] = 1;
				return true;
			} else {
				memory[i][j] = 2;
				return false;
			}
		}
		return false;
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

山海上的风

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

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

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

打赏作者

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

抵扣说明:

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

余额充值