小青蛙有一天不小心落入了一個地下迷宮,小青蛙希望用自己僅剩的體力值P跳出這個地下迷宮。
爲了讓問題簡單,假設這是一個n*m的格子迷宮,迷宮每個位置爲0或者1,0代表這個位置有障礙物,小青蛙達到不了這個位置;1代表小青蛙可以達到的位置。
小青蛙初始在(0,0)位置,地下迷宮的出口在(0,m-1)(保證這兩個位置都是1,並且保證一定有起點到終點可達的路徑),
小青蛙在迷宮中水平移動一個單位距離需要消耗1點體力值,向上爬一個單位距離需要消耗3個單位的體力值,向下移動不消耗體力值,
當小青蛙的體力值等於0的時候還沒有到達出口,小青蛙將無法逃離迷宮。現在需要你幫助小青蛙計算出能否用僅剩的體力值跳出迷宮(即達到(0,m-1)位置)。
輸入描述:
輸入包括n+1行。
第一行爲三個整數n,m(3 <= m,n <= 10),P(1 <= P <= 100)。接下來的n行,每行m個0或者1,以空格分隔。
輸出描述:
如果能逃離迷宮,則輸出一行體力消耗最小的路徑,輸出格式見樣例所示;如果不能逃離迷宮,則輸出”Can not escape!”。 測試數據保證答案唯一。
代碼如下:
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Scanner;
public class FrogMaze {
static int n = 0;
static int m = 0;
// 當前求解方案走完剩餘的能量
static int maxResidueEnergy = 0;
// 迷宮地圖
static int[][] map;
// 是否能出去
static boolean canSolve = false;
// 路徑
static String path = "";
// 保存當前走過的點
static LinkedList<String> linkedList = new LinkedList<>();
// 自定義測試用迷宮
static int[][] table = new int[][] {
{1, 0, 0, 0, 1, 0, 0, 1},
{1, 1, 0, 1, 1, 1, 0, 1},
{0, 1, 0, 1, 0, 1, 0, 1},
{0, 1, 1, 1, 0, 1, 0, 1},
{1, 0, 0, 0, 1, 1, 1, 1}
};
public static void main(String[] args) {
// 輸入操作
// Scanner scanner = new Scanner(System.in);
// while (scanner.hasNext()) {
// n = scanner.nextInt();
// m = scanner.nextInt();
// int p = scanner.nextInt();
// map = new int[n][m];
//
// // 迷宮地圖錄入
// for (int i = 0; i < n; i++) {
// for (int j = 0; j < m; j++) {
// map[i][j] = scanner.nextInt();
// }
// }
// 使用自定義測試
n = 5;
m = 8;
int p = 100;
map = table;
enterMaze(0, 0, p);
if (canSolve) {
System.out.println(path);
} else {
System.out.println("Can not escape!");
}
// }
}
public static void enterMaze(int x, int y, int energy) {
// 遞歸越界,能量耗完,當前點不能走
if (energy<0 || x<0 || y<0 || x>=n || y>=m || map[x][y]==0) {
return;
} else {
// "-"作爲分隔符,方便更新路線操作
linkedList.push("["+x+","+y+"]-");
// 將當前塊記0,使之後的點不能再走
map[x][y] = 0;
// 當前找到了出口
if (x==0 && y==m-1) {
// 本次方案剩餘的能量值比當前花費最少的方案剩餘的能量還多,進行最優路徑的更新
if (energy >= maxResidueEnergy) {
maxResidueEnergy = energy;
updatePath();
}
map[x][y] = 1;
canSolve = true;
return;
}
// 向上
enterMaze(x-1, y, energy-3);
// 向右
enterMaze(x, y+1, energy-1);
// 向下
enterMaze(x+1, y, energy);
// 向左
enterMaze(x, y-1, energy-1);
map[x][y] = 1;
linkedList.removeLast();
}
}
/**
*
*/
public static void updatePath() {
StringBuilder sb = new StringBuilder();
Iterator<String> iterator = linkedList.iterator();
while (iterator.hasNext()) {
sb.append(iterator.next());
}
path = null;
// 以 - 作爲分隔符切分
String[] paths = sb.toString().split("-");
sb.delete(0, sb.length());
for (int i = paths.length-1; i >= 0; i--) {
sb.append(paths[i]).append(",");
}
// 刪除最後一個","
if (sb.length() > 0) {
sb.deleteCharAt(sb.length()-1);
}
path = sb.toString();
}
}