小青蛙有一天不小心落入了一個地下迷宮,小青蛙希望用自己僅剩的體力值P跳出這個地下迷宮

 小青蛙有一天不小心落入了一個地下迷宮,小青蛙希望用自己僅剩的體力值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();
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章