题目大意:我们的主人公要躲避流星雨,要为她选择一条合适的逃生路线。流星雨会在不同时间落下,落下时会让周围4个坐标(上下左右)一起损坏,主人公每次移动一个坐标(上下左右),耗费一个单位时间。
思路:在坐标及其周围4个邻接坐标记上陨石落下时间(如果有重叠的话取最小时间),只有在当前时间小于落下时间才能走这个坐标,然后就可以愉快的BFS了。
然而我还是WA了两次……有两个注意点:
1、那个坐标范围0~300,0是边界,不能走到坐标比0小的位置,300只是流星落点的最远坐标,可以走到坐标大于300的位置(此时主人公就安全了)
2、落下的时间是0~1000,也就是说,陨石可以在0时刻落下(这个坑死我了,原本我就是用0来代表安全地方,后来改成用-1代表安全地带就可以了)
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
int map[310][310], T;
const int mx[] = { 0,-1,0,1 }, my[] = { -1,0,1,0 }, max_len = 300;
struct state {
int x, y;
state(int a = 0, int b = 0) :x(a), y(b) {}
};
queue<state> q;
int main()
{
memset(map, -1, sizeof(map));
int m, xi, yi, ti;
cin >> m;
for (int i = 0; i < m; i++)
{
cin >> xi >> yi >> ti;
if (map[xi][yi] == -1) map[xi][yi] = ti;
else map[xi][yi] = min(map[xi][yi], ti);
for (int j = 0; j < 4; j++)
{
int nx = xi + mx[j], ny = yi + my[j];
if (nx >= 0 && ny >= 0)
{
if (map[nx][ny] == -1) map[nx][ny] = ti;
else map[nx][ny] = min(map[nx][ny], ti);
}
}
}
if (map[0][0] == -1)
{
cout << T << endl;
return 0;
}
if (map[0][0] == 0)
{
cout << -1 << endl;
return 0;
}
state st(0, 0);
q.push(st);
map[0][0] = 0;
while (!q.empty())
{
int n = q.size();
T++;
for (int i = 0; i < n; i++)
{
state sta = q.front();
q.pop();
for (int j = 0; j < 4; j++)
{
int nx = sta.x + mx[j], ny = sta.y + my[j];
if (nx >= 0 && ny >= 0)
{
if (map[nx][ny] == -1)
{
cout << T << endl;
return 0;
}
else if (T < map[nx][ny])
{
q.push(state(nx, ny));
map[nx][ny] = T;
}
}
}
}
}
cout << -1 << endl;
return 0;
}