http://poj.org/problem?id=3669
题意:有一块地,某个坐标在某个时刻会落下一颗陨石,那个坐标就被摧毁了,以后再也不能经过。现在问从(0,0)开始,每移动一格如果要花时间1,那么最少花多少时间可以到达安全的地方(不会被陨石砸到)?
安全的地方就是指永远不会有陨石落下的地方,刚开始初始化的时候,让会被陨石砸到的地方标记上陨石最早落下的时间(注意对于每一个给出的坐标,它的上下左右也是会被砸的)。然后从(0,0)开始扩展,每到一格的最短时间如果小于陨石落下的时间,表明可以在那个时刻经过。最先到达一个没有标记陨石落下时间的坐标的时间,就是答案。
这道题有一个很坑的点,就是虽然题目给出的坐标<=300,但是可能人可以逃到比300大的坐标上。
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<queue>
#define INF 0x3f3f3f3f
#define N 450
using namespace std;
struct Node{
int x;
int y;
} p;
int m, x, y, t, X, Y, ans, x_, y_, limit[N][N], d[N][N];
const int dx[4] = {0, 1, -1, 0};
const int dy[4] = {1, 0, 0, -1};
int main()
{
scanf("%d", &m);
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
{
limit[i][j] = INF;
d[i][j] = INF;
}
for (int i = 0; i < m; i++)
{
scanf("%d%d%d", &x, &y, &t);
if (t < limit[x][y]) limit[x][y] = t;
for (int j = 0; j < 4; j++)
{
X = x + dx[j];
Y = y + dy[j];
if (X >= 0 && X <= N && Y >= 0 && Y <= N && t < limit[X][Y])
limit[X][Y] = t;
}
}
queue <Node> q;
while (q.size()) q.pop();
if (limit[0][0] == 0) ans = -1;
else
{
ans = -1;
p.x = 0;
p.y = 0;
q.push(p);
d[0][0] = 0;
while (q.size())
{
p = q.front();
q.pop();
X = p.x;
Y = p.y;
if (limit[X][Y] == INF)
{
ans = d[X][Y];
break;
}
else
{
for (int i = 0; i < 4; i++)
{
x_ = X + dx[i];
y_ = Y + dy[i];
if (x_ >= 0 && x_ <= N && y_ >= 0 && y_ <= N && d[x_][y_] == INF && d[X][Y]+1 < limit[x_][y_] )
{
d[x_][y_] = d[X][Y] + 1;
p.x = x_;
p.y = y_;
q.push(p);
}
}
}
}
}
printf("%d\n", ans);
return 0;
}