演算法程式設計(JAVA)--迷宮問題
阿新 • • 發佈:2019-01-03
最近遇到了一個經典的演算法問題--迷宮問題,自己試著用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+"步"); } } }