Meteor Shower
题目链接:
http://poj.org/problem?id=3669
解题思路:
给m个坐标,分别会在不同的t时刻下流星雨,请求出最少需要多长时间才能到达安全的地方,被流星雨摧毁的地方不能再走
了。。。
首先预处理,将流星出现的最早时间用vis数组标记,然后再用bfs搜索。。。注意数组要开到400多,不然会wrong。。。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
struct node{
int x,y,t;
};
const int dx[] = {0,-1,0,1,0},dy[] = {0,0,-1,0,1};
int vis[410][410];//嚓,题目数据有问题,开400才能过
bool check(int x,int y){
if(x<0 || x > 400 || y <0 || y > 400)
return false;
return true;
}
int bfs(){
if(vis[0][0] == 0)
return -1;
else if(vis[0][0] == -1)
return 0;
node cur;
cur.x = 0;cur.y = 0;cur.t = 0;
queue<node> q;
q.push(cur);
while(!q.empty()){
cur = q.front();
q.pop();
//printf("%d %d %d\n",cur.x,cur.y,cur.t);
node tmp;
for(int i = 1; i <= 4; i++){
tmp.x = cur.x+dx[i];tmp.y = cur.y+dy[i];tmp.t = cur.t+1;
if(!check(tmp.x,tmp.y))
continue;
if(vis[tmp.x][tmp.y] == -1)
return tmp.t;
if(vis[tmp.x][tmp.y] > cur.t+1){
vis[tmp.x][tmp.y] = tmp.t;//走过要记为标记
q.push(tmp);
}
}
}
return -1;
}
int main(){
int m;
while(~scanf("%d",&m)){
int x,y,t;
memset(vis,-1,sizeof(vis));
for(int i = 0; i < m; i++){
scanf("%d%d%d",&x,&y,&t);
for(int j = 0; j < 5; j++){
int xx = x+dx[j],yy = y+dy[j];
if(check(xx,yy)){
if(vis[xx][yy] == -1)
vis[xx][yy] = t;
else
vis[xx][yy] = min(vis[xx][yy],t);
}
}
}
printf("%d\n",bfs());
}
return 0;
}