流星雨
题目链接:None
题目大意
给出一个矩阵,有一些点从一些时刻开始就不能走了。
问你可以不可以走到一个永远都能走的点,如果可以就输出走到那个点的最短时间。
思路
直接按着条件跑 bfs。
一定要注意的是它只是说陨石落的范围是 300 以内,没有说不能走到三百外面的地方。
代码
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
struct zb {
int x, y;
};
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
int m, a[401][401], x, y, t, safe_num;
int number[401][401], ans;
queue <zb> q;
bool no, yes;
bool ck(int x, int y) {
if (x < 0) return 0;//只用判断左下的边界
if (y < 0) return 0;
return 1;
}
void bfs() {
if (a[0][0] == 0) {
no = 1;
return ;
}
q.push((zb){0, 0});
while (!q.empty()) {
zb now = q.front();
q.pop();
if (a[now.x][now.y] == safe_num) {
ans = number[now.x][now.y];
yes = 1;
return ;
}
for (int i = 0; i < 4; i++) {
int x = now.x + dx[i], y = now.y + dy[i];
if (ck(x, y)) {
if (!(x == 0 && y == 0) && !number[x][y]) {
if (number[now.x][now.y] + 1 < a[x][y]) {
number[x][y] = number[now.x][now.y] + 1;
q.push((zb){x, y});
}
}
}
}
}
no = 1;
}
int main() {
// freopen("meteor.in", "r", stdin);
// freopen("meteor.out", "w", stdout);
memset(a, 0x7f, sizeof(a));
safe_num = a[0][0];
scanf("%d", &m);
for (int i = 1; i <= m; i++) {
scanf("%d %d %d", &x, &y, &t);
a[x][y] = min(a[x][y], t);
a[x + 1][y] = min(a[x + 1][y], t);
a[x][y + 1] = min(a[x][y + 1], t);
if (x - 1 >= 0) a[x - 1][y] = min(a[x - 1][y], t);
if (y - 1 >= 0) a[x][y - 1] = min(a[x][y - 1], t);
}
bfs();
if (no || !yes) printf("-1");
else printf("%d", ans);
fclose(stdin);
fclose(stdout);
return 0;
}