...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;
}
}
注意:
這個問題的解法在二維數組的"走動"類問題上適用性上具有很好的普遍性,在解法中,可以將向上,向下,向左,向右的邏輯算法同時列舉, 但是這樣看起來不簡潔,可以使用一個小技巧,使用int[][] d 來操作上下左右的移動,詳見我的另一篇文章:
島嶼的數量:
https://blog.csdn.net/qq_35394891/article/details/84404156
迷宮問題要比島嶼的數量問題稍簡單
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)));
}
}