Meteor Shower POJ - 3669
Bessie听说有场史无前例的流星雨即将来临;有谶言:陨星将落,徒留灰烬。为保生机,她誓将找寻安全之所(永避星坠之地)。目前她正在平面坐标系的原点放牧,打算在群星断其生路前转移至安全地点。
此次共有M (1 ≤ M ≤ 50,000)颗流星来袭,流星i将在时间点Ti (0 ≤ Ti ≤ 1,000) 袭击点 (Xi, Yi) (0 ≤ Xi ≤ 300; 0 ≤ Yi ≤ 300)。每颗流星都将摧毁落点及其相邻四点的区域。
Bessie在0时刻时处于原点,且只能行于第一象限,以平行与坐标轴每秒一个单位长度的速度奔走于未被毁坏的相邻(通常为4)点上。在某点被摧毁的刹那及其往后的时刻,她都无法进入该点。
寻找Bessie到达安全地点所需的最短时间。
Input
- 第1行: 一个整数: M
- 第2…M+1行: 第i+1行包含由空格分隔的三个整数: Xi, Yi, and Ti
Output
- 仅一行: Bessie寻得安全点所花费的最短时间,无解则为-1。
Examples
Sample Input - 输入样例
4
0 0 2
2 1 2
1 1 2
0 3 5
Sample Output - 输出样例
5
Hint
题解:
二维数组存一下当前(x,y)坐标的时间, 每次要走过后要更新数组, 不然会T
注意人是可以走过300的
经验小结:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
#define ms(x, n) memset(x,n,sizeof(x));
typedef long long LL;
const int inf = 1 << 30;
const int maxn = 310;
const int maxm = 50010;
struct node{
int x, y, t;
};
int maze[maxn][maxn]; //每一个坐标的时间
int act[5][2] = {{0,0},{1,0},{0,1},{0,-1},{-1,0}};
bool judge(int x, int y){
return x>=0&&y>=0;
}
int Bfs(){
queue<node> q;
if(maze[0][0] > 0)
q.push(node{0, 0, 0});
while(!q.empty()){
node cur = q.front();
q.pop();
int x = cur.x, y = cur.y, t = cur.t;
if(maze[x][y] == inf)
return t;
int cx, cy;
for(int i = 1; i < 5; ++i){
cx = x+act[i][0], cy = y+act[i][1];
if(cx>=0&&cy>=0 && t+1 < maze[cx][cy]){
if(maze[cx][cy]!=inf)
maze[cx][cy] = t+1; //最优化剪枝
q.push(node{cx, cy, t+1});
}
}
}
return -1;
}
int main() {
ios::sync_with_stdio(false);
fill(maze[0], maze[0]+maxn*maxn, inf);
int M, x, y, t;
cin >> M;
for(int i = 1; i <= M; ++i){
cin >> x >> y >> t;
int cx, cy;
for(int i = 0; i < 5; ++i){
cx = x+act[i][0], cy = y+act[i][1];
if(cx>=0&&cx<=300&&cy>=0&&cy<=300)
maze[cx][cy] = min(maze[cx][cy], t);
}
}
cout << Bfs() << endl;
return 0;
}