[Java] 藍橋杯ADV-147 演算法提高 學霸的迷宮

柳婼發表於2018-10-10

問題描述
學霸搶走了大家的作業,班長為了幫同學們找回作業,決定去找學霸決鬥。但學霸為了不要別人打擾,住在一個城堡裡,城堡外面是一個二維的格子迷宮,要進城堡必須得先通過迷宮。因為班長還有妹子要陪,磨刀不誤砍柴功,他為了節約時間,從線人那裡搞到了迷宮的地圖,準備提前計算最短的路線。可是他現在正向妹子解釋這件事情,於是就委託你幫他找一條最短的路線。
輸入格式
第一行兩個整數n, m,為迷宮的長寬。
接下來n行,每行m個數,數之間沒有間隔,為0或1中的一個。0表示這個格子可以通過,1表示不可以。假設你現在已經在迷宮座標(1,1)的地方,即左上角,迷宮的出口在(n,m)。每次移動時只能向上下左右4個方向移動到另外一個可以通過的格子裡,每次移動算一步。資料保證(1,1),(n,m)可以通過。

輸出格式
第一行一個數為需要的最少步數K。
第二行K個字元,每個字元∈{U,D,L,R},分別表示上下左右。如果有多條長度相同的最短路徑,選擇在此表示方法下字典序最小的一個。

樣例輸入
Input Sample 1:
3 3
001
100
110
Input Sample 2:
3 3
000
000
000
樣例輸出
Output Sample 1:
4
RDRD
Output Sample 2:
4
DDRR
資料規模和約定
有20%的資料滿足:1<=n,m<=10
有50%的資料滿足:1<=n,m<=50
有100%的資料滿足:1<=n,m<=500。

package adv147;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {

    public static int isVisited[][];

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        char[][] maze = new char[n][m];
        isVisited = new int[n][m];
        for (int i = 0; i < n; i++) {
            maze[i] = in.next().toCharArray();
        }
        in.close();

        Queue queue = new LinkedList<>();
        queue.add(new Index(0, 0));
        Index e = new Index(n-1, m-1);
        isVisited[0][0] = 1;
        bfs(maze, queue, e);
        printPath(n-1, m-1, n, m);
    }

    public static void bfs(char[][] maze, Queue q, Index e) {
        Queue queue = new LinkedList<>();

        while (!q.isEmpty()) {
            Index s = q.poll();

            if (s.equals(e)) {
                System.out.println(isVisited[s.r][s.l] - 1);
                return;
            }

            // Down
            if (s.r + 1 <= e.r && isVisited[s.r + 1][s.l] == 0 && maze[s.r+1][s.l] == '0') { queue.add(new Index(s.r + 1, s.l)); isVisited[s.r+1][s.l] = isVisited[s.r][s.l] + 1; } // Left if (s.l >= 1 && isVisited[s.r][s.l - 1] == 0 && maze[s.r][s.l - 1] == '0') {
                queue.add(new Index(s.r, s.l - 1));
                isVisited[s.r][s.l - 1] = isVisited[s.r][s.l] + 1;
            }

            // Right
            if (s.l + 1 <= e.l && isVisited[s.r][s.l + 1] == 0 && maze[s.r][s.l + 1] == '0') { queue.add(new Index(s.r, s.l+1)); isVisited[s.r][s.l + 1] = isVisited[s.r][s.l] + 1; } // Up if (s.r >= 1 && isVisited[s.r - 1][s.l] == 0 && maze[s.r - 1][s.l] == '0') {
                queue.add(new Index(s.r - 1, s.l));
                isVisited[s.r - 1][s.l] = isVisited[s.r][s.l] + 1;
            }
        }

        bfs(maze, queue, e);
    }

    public static void printPath(int r, int l, int n, int m) {
        if (r == 0 && l == 0) {
            return;
        }

        if (r+1 < n && isVisited[r][l] - 1 == isVisited[r+1][l]) { // Down printPath(r+1, l, n, m); System.out.print("U"); } else if (l>=1 && isVisited[r][l] - 1 == isVisited[r][l-1]) {
            // Left
            printPath(r,l-1, n, m);
            System.out.print("R");
        } else if (l +1 < m && isVisited[r][l] - 1 == isVisited[r][l+1]) { // Right printPath(r, l+1, n, m); System.out.print("L"); } else if (r >= 1 && isVisited[r][l] - 1 == isVisited[r-1][l]) {
            // Up
            printPath(r-1, l, n, m);
            System.out.print("D");
        }
    }


}

class Index {
    int r;
    int l;

    public Index (int r, int l) {
        this.r = r;
        this.l = l;
    }

    public boolean equals(Index e) {
        return r == e.r && l == e.l;
    }

}

 

相關文章