[Java] 藍橋杯ADV-147 演算法提高 學霸的迷宮
問題描述
學霸搶走了大家的作業,班長為了幫同學們找回作業,決定去找學霸決鬥。但學霸為了不要別人打擾,住在一個城堡裡,城堡外面是一個二維的格子迷宮,要進城堡必須得先通過迷宮。因為班長還有妹子要陪,磨刀不誤砍柴功,他為了節約時間,從線人那裡搞到了迷宮的地圖,準備提前計算最短的路線。可是他現在正向妹子解釋這件事情,於是就委託你幫他找一條最短的路線。
輸入格式
第一行兩個整數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;
}
}
相關文章
- 藍橋杯-演算法提高 學霸的迷宮(BFS-倒向追蹤輸出移動方向)演算法
- 藍橋杯-走迷宮(BFS)
- 藍橋杯-迷宮(BFS+DFS)
- 試題集—— 演算法提高 學霸的迷宮演算法
- 藍橋杯演算法提高——字串匹配(Java)演算法字串匹配Java
- 藍橋杯-地宮取寶
- 藍橋杯 演算法提高 字串壓縮演算法字串
- Java實現 藍橋杯 演算法提高 八數碼(BFS)Java演算法
- [藍橋杯][演算法提高VIP]尤拉函式演算法函式
- [藍橋杯][演算法提高VIP]超級瑪麗演算法
- [藍橋杯][演算法提高VIP]大數加法演算法
- [藍橋杯][演算法提高VIP]奪寶奇兵 dp演算法
- [Java] 藍橋杯ADV-203 演算法提高 8皇后·改Java演算法
- 藍橋杯 演算法提高 P0102(Java解題)演算法Java
- 藍橋杯 -- 演算法提高 身份證號碼升級演算法
- [藍橋杯][演算法提高VIP]分蘋果 線段樹演算法蘋果
- 藍橋杯 演算法提高 拿糖果(完全揹包dp)演算法
- [Java] 藍橋杯ADV-213 演算法提高 3-2求存款Java演算法
- 藍橋杯 (java)演算法訓練 數對Java演算法
- [Java] 藍橋杯ADV-185 演算法提高 五次方數Java演算法
- 藍橋杯—演算法訓練演算法
- 藍橋杯--演算法訓練演算法
- 題目 1501: [藍橋杯][演算法提高VIP]分蘋果演算法蘋果
- [Java] 藍橋杯ADV-194 演算法提高 盾神與積木遊戲Java演算法遊戲
- [Java] 藍橋杯ADV-202 演算法提高 最長公共子序列Java演算法
- [Java] 藍橋杯ADV-209 演算法提高 c++_ch02_04Java演算法C++
- [Java] 藍橋杯ADV-210 演算法提高 2-1螢幕列印Java演算法
- 藍橋杯學習路線
- 藍橋杯 排序排序
- 藍橋杯 演算法訓練 素因子去重(Java)演算法Java
- 藍橋杯 分巧克力(Java)Java
- [藍橋杯][演算法提高VIP]最大乘積 貪心 雙指標演算法指標
- 藍橋杯_演算法提高_身份證升級(簡單字元處理)演算法字元
- 2016藍橋杯演算法提高——身份證號碼升級演算法
- 藍橋杯 演算法訓練 K好數(Java解題)演算法Java
- 藍橋杯 (java) 第39級階梯Java
- Java藍橋杯14年第五題Java
- 藍橋杯——Java基礎(進位制)Java