|
|
#include <bits/stdc++.h>
|
|
|
|
|
|
using namespace std;
|
|
|
const int INF = 0x3f3f3f3f;
|
|
|
const int N = 310;
|
|
|
|
|
|
//二维坐标系中每个点的上下左右变化delta坐标
|
|
|
int dx[] = {0, 0, -1, 1};
|
|
|
int dy[] = {1, -1, 0, 0};
|
|
|
|
|
|
int a[N][N]; //x,y坐标的最早被流星覆盖到的时间
|
|
|
int st[N][N]; //访问过的标识+从原点出发需要走几步到达这个位置
|
|
|
|
|
|
//定义结构体,x,y这个坐标,到达需要step步骤
|
|
|
struct coord {
|
|
|
int x, y;
|
|
|
};
|
|
|
|
|
|
//广度优先搜索
|
|
|
int bfs() {
|
|
|
queue<coord> q;
|
|
|
|
|
|
//出发的原点位置
|
|
|
q.push({0, 0});
|
|
|
|
|
|
//标识走过了0步,到达了这个位置
|
|
|
st[0][0] = 0;
|
|
|
|
|
|
//广度优先搜索的框架
|
|
|
while (!q.empty()) {
|
|
|
//队列首
|
|
|
coord u = q.front();
|
|
|
//出队列
|
|
|
q.pop();
|
|
|
//四个方向
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
int nx = u.x + dx[i];
|
|
|
int ny = u.y + dy[i];
|
|
|
//出了第一象限是不可以的
|
|
|
if (nx < 0 || ny < 0)continue;
|
|
|
|
|
|
//如果这个点为INF,表示永远不会被摧毁,已经安全了
|
|
|
if (a[nx][ny] == INF) return st[nx][ny] = st[u.x][u.y] + 1;
|
|
|
|
|
|
//如果到达这个时间点的时间早于最早摧毁时间,可以走
|
|
|
if (st[u.x][u.y] + 1 < a[nx][ny] && st[nx][ny] == -1) {
|
|
|
st[nx][ny] = st[u.x][u.y] + 1;
|
|
|
q.push({nx, ny});
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
int main() {
|
|
|
//初始化为INF(预求最小,先设最大)
|
|
|
memset(a, 0x3f, sizeof a);
|
|
|
|
|
|
//初始化为-1,表示没有走过
|
|
|
memset(st, -1, sizeof st);
|
|
|
|
|
|
//一共m个流星
|
|
|
int m;
|
|
|
cin >> m;
|
|
|
for (int i = 1; i <= m; i++) {
|
|
|
int x, y, t;
|
|
|
cin >> x >> y >> t;
|
|
|
|
|
|
//预处理的过程
|
|
|
//Q:预处理的是什么?
|
|
|
//A:每个点,都有一个最早的破坏时间,可能是直接被砸中,也可能是被牵连~,那么,这个点,
|
|
|
// 是什么时间被一次覆盖到呢?需要预处理出来
|
|
|
//求出该点和周围点的最早摧毁时间
|
|
|
a[x][y] = min(a[x][y], t); //如果直接砸中的时间小于原来记录的时间,需要修改一下。
|
|
|
for (int j = 0; j < 4; j++) {
|
|
|
//可以到达的新坐标位置
|
|
|
int nx = x + dx[j];
|
|
|
int ny = y + dy[j];
|
|
|
//一直在第一象限行动,只要nx,ny不小于0,可以随意向右,向上去走,右和上没有边界
|
|
|
if (nx >= 0 && ny >= 0) a[nx][ny] = min(a[nx][ny], t);
|
|
|
}
|
|
|
}
|
|
|
//广度优先搜索
|
|
|
printf("%d\n", bfs());
|
|
|
return 0;
|
|
|
}
|
|
|
|