技巧
优先队列 BFS
思路
能走则走。 如果有更优选择就更新重走。
实现
import java.io.*;
import java.util.*;
public class Main {
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
static class Pos {
int x;
int y;
int time;
public Pos(int x, int y, int time) {
this.x = x;
this.y = y;
this.time = time;
}
}
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
// 符合规则的四个移动方向
int[][] d = new int[][]{{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
while (true) {
String nmq = br.readLine();
if (nmq == null) {
break;
}
String[] nmqStrArr = nmq.split(" ");
int n = Integer.parseInt(nmqStrArr[0]), m = Integer.parseInt(nmqStrArr[1]), q = Integer.parseInt(nmqStrArr[2]);
char[][] maze = new char[n][m];
int[][] visit = new int[n][m];
// 开始 结束 位置坐标
int sx = 0, sy = 0;
for (int r = 0; r < n; r++) {
char[] mazeLine = br.readLine().toCharArray();
for (int c = 0; c < m; c++) {
maze[r][c] = mazeLine[c];
visit[r][c] = Integer.MAX_VALUE;
if (maze[r][c] == 'S') {
sx = r;
sy = c;
} else if (maze[r][c] == '#') {
visit[r][c] = -1;
}
}
}
// key: 输入位置 x y val: 输出坐标 x1 y1
Map<String, List<String>> qMap = new HashMap<>();
for (int i = 0; i < q; i++) {
String[] qStr = br.readLine().split(" ");
// 两端有陷阱的传送没有意义
if (maze[Integer.parseInt(qStr[0])][Integer.parseInt(qStr[1])] == '#'
|| maze[Integer.parseInt(qStr[2])][Integer.parseInt(qStr[3])] == '#') {
continue;
}
String k = qStr[0] + " " + qStr[1];
String v = qStr[2] + " " + qStr[3];
if (!qMap.containsKey(k)) {
qMap.put(k, new ArrayList<>());
}
qMap.get(k).add(v);
}
int ans = -1;
PriorityQueue<Pos> pq = new PriorityQueue<>(Comparator.comparingInt(o -> o.time));
pq.add(new Pos(sx, sy, 0));
visit[sx][sy] = 0;
while (!pq.isEmpty()) {
Pos poll = pq.poll();
if (maze[poll.x][poll.y] == 'T') {
ans = poll.time;
break;
}
// 四个方向尝试
for (int i = 0; i < 4; i++) {
int nx = poll.x + d[i][0];
int ny = poll.y + d[i][1];
if (nx < 0 || ny < 0 || nx >= n || ny >= m || visit[nx][ny] == -1 || poll.time + 1 >= visit[nx][ny]) {
continue;
}
pq.add(new Pos(nx, ny, poll.time + 1));
visit[nx][ny] = poll.time + 1;
}
// 传送
String key = poll.x + " " + poll.y;
if (qMap.containsKey(key)) {
List<String> out = qMap.get(key);
for (String o : out) {
String[] targetPos = o.split(" ");
int tx = Integer.parseInt(targetPos[0]);
int ty = Integer.parseInt(targetPos[1]);
if (poll.time + 3 >= visit[tx][ty]) {
continue;
}
pq.add(new Pos(tx, ty, 3 + poll.time));
visit[tx][ty] = poll.time + 3;
}
}
}
out.println(ans);
}
out.flush();
}
}

京公网安备 11010502036488号