算法编程(JAVA)--迷宫问题

最近遇到了一个经典的算法问题--迷宫问题,自己试着用JAVA编写了一下,感觉还比较简单,直接贴题目和代码了。

题目:一个网格迷宫由n行m列的单元格组成,每个大院个要么是空地(用“.”表示),要么是障碍物(用"#"表示)。你的任务是找一条从起点到终点的最短移动序列,其中只能上下左右移动到相邻单元格。任何时候都不能在有障碍物的单元格中,也不能走到迷宫之外。起点为“S”和终点“G”。n,m<100。

主要思路:先找到起点,然后出起点出发,一直走走到死路时,再原路返回,返回到岔路口,选择另一条路接着走。每到一个岔路口就按固定的顺序选择尝试,防止重复走。使用一个二维数组表示迷宫地图,通过深度搜索来找寻出口,本次编写并没有用到堆栈对象,只是用了简单的递归,代码后面有详细的注释,希望你们能轻松看懂

import java.util.Scanner;

public class Main
{
	static int lineX,lineY;//迷宫矩阵的长度和宽度
	static int startX,startY;//起始位置的坐标
	static String[][] arr;//迷宫的二维数组
	static int count=10000;//走的最少步数,初始值设置为10000意为无穷
	public static void main(String[] args){
		Input();//输入函数
		Running(startX,startY,0);//递归函数
		Output();//输出函数
	}
	public static void Input(){
		Scanner sc = new Scanner(System.in);
		lineX = Integer.parseInt(sc.next());//获取迷宫长宽
		lineY = Integer.parseInt(sc.next());
		arr = new String[lineX][lineY];//初始化迷宫数组
		for(int i=0;i<lineX;i++){
			String str = sc.next();
			AddToArr(str,i);//将每一个符号放入二维数组
		}
	}
	public static void AddToArr(String str,int n){
		for(int i=0;i<lineY-1;i++){
			arr[n][i]=str.substring(i,i+1);
			setStart(str.substring(i,i+1),n,i);//寻找起始位置
		}
		arr[n][lineY-1]=str.substring(lineY-1);
		setStart(str.substring(lineY-1),n,lineY-1);
	}
	public static void setStart(String a,int x,int y){		
		if(a.equals("S")){
			startX=x;
			startY=y;
		}			
	}
	/************递归函数************/
	public static void Running(int x,int y,int n){
		//System.out.println(x+" "+y+" "+n);//打印每一步方便理解
		/*判断上下左右有没有终点*/
		if(y-1>=0&&arr[x][y-1].equals("G")){
			Running(x,y-1,n+1);
		}
		if(x-1>=0&&arr[x-1][y].equals("G")){
			Running(x-1,y,n+1);
		}
		if(y+1<lineY&&arr[x][y+1].equals("G")){
			Running(x,y+1,n+1);
		}
		if(x+1<lineX&&arr[x+1][y].equals("G")){
			Running(x+1,y,n+1);
		}
		/*如果是终点就将最短路径记录一下,然后退出此次函数*/
		if(arr[x][y].equals("G")){
			if(n<count)
				count=n;
			return;
		}
		arr[x][y]="*";//若非终点,将该点做个记号"*"表示已经走过,使以后不再走到这个位置
		/*判断上下左右有没有可以走的路*/
		if(y-1>=0&&arr[x][y-1].equals(".")){
			Running(x,y-1,n+1);
		}
		if(x-1>=0&&arr[x-1][y].equals(".")){
			Running(x-1,y,n+1);
		}
		if(y+1<lineY&&arr[x][y+1].equals(".")){
			Running(x,y+1,n+1);
		}
		if(x+1<lineX&&arr[x+1][y].equals(".")){
			Running(x+1,y,n+1);
		}
		//若没有可以走的路就将此处的记号取消,变回"."
		arr[x][y]=".";
		return;
	}
	public static void Output(){
		if(count==10000){
			System.out.println("没有出口!");
		}
		else{
			System.out.println("最少需要"+count+"步");
		}
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值