迷宫问题(图)

...11111111111111111111111111111
11.111111........1111111111.1111
11.111111..111.11111111.....1111
11.11111111111.1111111111.111111
11.111111.................111111
11.111111.11111111111.11111.1111
11.111111.11111111111.11111..111
11..........111111111.11111.1111
11111.111111111111111.11....1111
11111.111111111111111.11.11.1111
11111.111111111111111.11.11.1111
111...111111111111111.11.11.1111
111.11111111111111111....11.1111
111.11111111111111111111111.1111
111.1111.111111111111111......11
111.1111.......111111111.1111.11
111.1111.11111.111111111.1111.11
111......11111.111111111.1111111
11111111111111.111111111.111...1
11111111111111...............1.1
111111111111111111111111111111..

如上图的迷宫,入口,出口分别:左上角,右下角
"1"是墙壁,"."是通路

求最短需要走多少步?

测试数据1:

21 32 
...11111111111111111111111111111
11.111111........1111111111.1111
11.111111..111.11111111.....1111
11.11111111111.1111111111.111111
11.111111.................111111
11.111111.11111111111.11111.1111
11.111111.11111111111.11111..111
11.................11.11111.1111
11111.111111111111.11.11....1111
11111.111111111111.11.11.11.1111
11111.111111111111.11.11.11.1111
111...111111111111.11.11.11.1111
111.11111111111111.11....11.1111
111.11111111111111.11111111.1111
111.1111.111111111.11111......11
111.1111.......111.11111.1111.11
111.1111.11111.111.11111.1111.11
111......11111.111.11111.1111111
11111111111111.111.11111.111...1
11111111111111...............1.1
111111111111111111111111111111..

答案:53

测试数据2:

21 32
...11111111111111111111111111111
11.111111........1111111111.1111
11.111111..111.11111111.....1111
11.11111111111.1111111111.111111
11.111111.................111111
11.111111.11111111111.11111.1111
11.111111.11111111111.11111..111
11..........111111111.11111.1111
11111.111111111111111.11....1111
11111.111111111111111.11.11.1111
11111.111111111111111.11.11.1111
111...111111111111111.11.11.1111
111.11111111111111111....11.1111
111.11111111111111111111111.1111
111.1111.111111111111111......11
111.1111.......111111111.1111.11
111.1111.11111.111111111.1111.11
111......11111.111111111.1111111
11111111111111.111111111.111...1
11111111111111...............1.1
111111111111111111111111111111..

答案:61

DFS做法

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class Main {
	
	//行号
	static int row ;
	//列号
	static int col ;
    public static void main(String[] args) throws FileNotFoundException { 
    	
    	
    	Scanner input = new Scanner(System.in);
    	//分割字符串,得到即将输入二维数组的行和列
    	//" +"是一个正则表达式,代表安装一个以上的空格进行分割
    	String[] ss = input.nextLine().trim().split(" +");
    	row = Integer.parseInt(ss[0]);
    	col = Integer.parseInt(ss[1]);;
    	
    	
    	
    	char[][] data = new char[row][col];
    	for(int i=0;i<row;i++){
    		data[i] = input.next().toCharArray();
    	}
    	
    	
    	
		System.out.println(min_path(data,0,0));
		
    }  
    
    public static int min_path(char[][] data,int x,int y){
    	//当走到最后一个位置 右下角的时候
    	//根据题目规定 我们是从 0,0出发的 
    	//假设 终点是 0,1  那么走到终点应该返回一个0
    	//代表只走一步就到达了终点
    	//可以理解成: 从 0,0 走到 0,0 只需要 0 步
    	if(x==row-1&&y==col-1){
    		return 0;
    	}
    	
    	//走到该位置 加上标记防止 往回走 
    	data[x][y] = '*';
    	
    	//现在走到终点的最小步数   初始值为Integer最大值 (-10 是为了 防止在+1后溢出)
    	int min = Integer.MAX_VALUE-10;
    	
    	//尝试向上走需要多少步。
		if (x > 0 && data[x-1][y]=='.') {
			//判断该向上走需要的步数是否是最小步数
			min = Math.min(min, 1 + min_path(data, x - 1, y));
		}
		
		//向下
		if (x < row-1 && data[x+1][y]=='.') {
			min = Math.min(min, 1 + min_path(data, x + 1, y));
		}
		
		//向左
		if (y > 0 && data[x][y-1]=='.'){
			min = Math.min(min, 1 + min_path(data, x, y - 1));
		}
		
		//向右
		if (y < col-1 && data[x][y+1]=='.') {
			min = Math.min(min, 1 + min_path(data, x, y + 1));
		} 
		
		
		//回溯在递归测试完毕找到所有最短路径后
		//将该位置复原 (既然可以走到该位置,该位置肯定是.)
		data[x][y] = '.';
		
		//如果,四个方向都没有走通,那么min还是初始值 Integer的最小值
		//代表该位置作废 走不通
		return min;
    }

    
}  

BFS做法

用本次的状态去派生出下次的状态,

直到有一次状态里有终点位置,说明找到了终点。

感觉比dfs快一点。

import java.util.*;

public class A
{
	// from: 出发位置  goal: 目标位置
	static int f(char[][] data, Set from, String goal){
		if(from.contains(goal)) return 0; // 达到了最终的位置
		
		Set set = new HashSet(); // 找到from的相邻连通点
		
		for(Object obj: from){
			String[] ss = ((String)obj).split(",");
			int y = Integer.parseInt(ss[0]);
			int x = Integer.parseInt(ss[1]);
			
			if(y>0 && data[y-1][x]=='.'){ data[y-1][x] = '*'; set.add(y-1+","+x); }
			if(y<data.length-1 && data[y+1][x]=='.'){ data[y+1][x] = '*'; set.add(y+1+","+x); }
			if(x>0 && data[y][x-1]=='.'){ data[y][x-1] = '*'; set.add(y+","+(x-1)); }
			if(x<data[0].length-1 && data[y][x+1]=='.'){ data[y][x+1] = '*'; set.add(y+","+(x+1)); }
		}
		//没有找到任何后序可行的策略
		if(set.isEmpty()) return -1;
		int r = f(data, set, goal);
		if(r<0) return -1;
		return r + 1;
	}
	
	public static void main(String[] args){
		Scanner scan = new Scanner(System.in);
		
		String[] ss = scan.nextLine().trim().split(" +");
		int n = Integer.parseInt(ss[0]);
		int m = Integer.parseInt(ss[1]);
		
		char[][] data = new char[n][];
		for(int i=0; i<n; i++){
			data[i] = scan.nextLine().trim().toCharArray();
		}
		
		Set set = new HashSet();
		set.add("0,0");
		System.out.println(f(data, set, n-1 + "," + (m-1)));
	}
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SUNbrightness

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

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

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

打赏作者

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

抵扣说明:

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

余额充值