最近遇到了一个经典的算法问题–迷宫问题,自己试着用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+"步");
}
}
}