运用bfs算法
蒜头君要回家,但是他家的钥匙在他的朋友花椰妹手里,他要先从花椰妹手里取得钥匙才能回到家。花椰妹告诉他:“你家的钥匙被我复制了很多个,分别放在不同的地方。”
蒜头君希望能尽快回到家中,他需要首先取得任意一把钥匙,请你帮他计算出回家所需要的最短路程。
蒜头君生活的城市可以看做是一个n×m的网格,其中有道路有障碍,钥匙和家所在的地方可以看做是道路,可以通过。蒜头君可以在城市中沿着上下左右4个方向移动,移动一个格子算做走一步。
输入格式
第一行有两个整数n,m。城市的地图是n行m列。(1≤n,m≤2000)
接下来的n行,每行m个字符,代表城市的地图。'.' 代表道路,'#' 代表障碍物,'S' 代表蒜头君所在的位置,'T' 代表蒜头家的位置,'P'代表钥匙的位置。除了障碍物以外,别的地方都可以通过。(题目保证蒜头君至少有一条路径可以顺利拿到钥匙并且回家)
输出格式
输出蒜头回家要走的最少步数,占一行。
样例输入
8 10
P.####.#P#
..#..#...#
..#T##.#.#
..........
..##.#####
..........
#####...##
###....S##
样例输出
21
// 蒜头君回家
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
static class Node {
int x;
int y;
int step;
int key = 0;
public Node(int x, int y, int step, int key) {
this.x = x;
this.y = y;
this.step = step;
this.key = key;
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
int sx = 0;
int sy = 0;
char[][] map = new char[n][m];
int[][][] vis = new int[n + 5][m + 5][2];
int[][] dir = { {-1, 0},{0, 1},{1, 0},{0, -1} };
for (int i = 0; i < n; i++) {
String str = in.next();
for (int j = 0; j < m; j++) {
map[i][j] = str.charAt(j);
if(map[i][j] == 'S') {
sx = i;
sy = j;
}
}
}
Node start = new Node(sx, sy, 0, 0);
Queue<Node> queue = new LinkedList<Node>();
queue.add(start);
Node now = start;
vis[sx][sy][0] = 1;
while(!queue.isEmpty()) {
now = queue.poll();
int x = now.x;
int y = now.y;
int step = now.step;
int key = now.key;
if(map[x][y] == 'P') {
key = 1;
vis[x][y][1] = 1;
}
if(map[x][y] == 'T' && key == 1) {
System.out.println(now.step);
return;
}
for (int i = 0; i < 4; i++) {
int tx = x + dir[i][0];
int ty = y + dir[i][1];
if(tx < 0 || tx >= n || ty < 0 || ty >= m) continue;
if(map[tx][ty] != '#' && vis[tx][ty][key] == 0) {
vis[tx][ty][key] = 1;
Node next = new Node(tx, ty, step + 1, key);
queue.add(next);
}
}
}
}
}