点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 400;
const int INF = 1e9; //代表绝对安全
//存储被流星砸中的最早时间
int grid[MAXN][MAXN];
//既存储步数又起到vis数组的作用
int dist[MAXN][MAXN];
// 方向数组
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
struct Point {
int x, y;
};
int bfs() {
//做一个特判,如果起点在一开始就被砸了直接返回-1
if (grid[0][0] == 0) return -1;
//初始化与启动
queue<Point> q;
memset(dist, -1, sizeof(dist));
q.push({0, 0});
dist[0][0] = 0;
while (!q.empty()) {
//取出队头
Point u = q.front();
q.pop();
// 终点判断,如果当前脚下的是永久安全区,那就直接返回
if (grid[u.x][u.y] == INF) {
return dist[u.x][u.y];
}
//观察邻居
for (int i = 0; i < 4; i++) {
int nx = u.x + dx[i];
int ny = u.y + dy[i];
// 下一步的时刻
int next_time = dist[u.x][u.y] + 1;
//判断与选择,不越界,没去过,安全性
if (nx >= 0 && nx < MAXN && ny >= 0 && ny < MAXN &&
dist[nx][ny] == -1 &&
next_time < grid[nx][ny]) { // 核心:比流星快一步
dist[nx][ny] = next_time;
q.push({nx, ny});
}
}
}
//结束
return -1;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
//初始地图为绝对安全
for (int i = 0; i < MAXN; i++) {
for (int j = 0; j < MAXN; j++) {
grid[i][j] = INF;
}
}
int m;
cin >> m;
while (m--) {
int x, y, t;
cin >> x >> y >> t;
// 标记中心点,取最小值
grid[x][y] = min(grid[x][y], t);
// 标记四周 4 个点
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx >= 0 && nx < MAXN && ny >= 0 && ny < MAXN) {
grid[nx][ny] = min(grid[nx][ny], t);
}
}
}
cout << bfs() << endl;
return 0;
}