感悟与理解
1、
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 310;
//二维坐标系中每个点的上下左右变化delta坐标
int dx[4] = {0, 0, -1, 1};
int dy[4] = {1, -1, 0, 0};
int a[N][N]; //x,y坐标的最早被流星覆盖到的时间
bool st[N][N]; //x,y坐标是不是已经走过,防止走回头路
//定义结构体,x,y这个坐标,到达需要step步骤
struct coord {
int x, y;
int step;
};
//广度优先搜索
int bfs() {
queue<coord> q;
//出发的原点位置
q.push({0, 0, 0});
//标识走过了
st[0][0] = true;
//广度优先搜索的框架
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;
//多走一步啊
int step = u.step + 1;
//如果这个点为INF,表示永远不会被摧毁,已经安全了
if (a[nx][ny] == INF)return step;
//如果到达这个时间点的时间早于最早摧毁时间,可以走
if (step < a[nx][ny] && !st[nx][ny]) {
st[nx][ny] = true;
q.push({nx, ny, step});
}
}
}
return -1;
}
int main() {
//初始化为INF(预求最小,先设最大)
memset(a, 0x3f, sizeof a);
//一共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;
}