题目请戳这里
题目大意:在二维平面上,有个人一开始在原点,现在有一场流星雨,已知有n个,第i个流星第ti秒落在(xi,yi)位置,并且(xi,yi)周围4个位置也会遭殃.人每秒走单位长度,并且只能向四个方向走,并且走的位置要在流行毁灭这一点之前.求这个人最快脱险时间.无法脱险输出-1.
题目分析:简单搜索,bfs妥妥的.首先用flag数组记录下所有位置最先遭殃的时间.然后从源点开始bfs.直到找到一个安全的地点为止.
trick:题目描述有误,二维平面范围不止300!要大一点!!
详情请见代码:
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 402; const int M = 50005; const int NM = 50004; const int inf = 0x3f3f3f3f; struct node { int x,y,t; bool operator< (const node a)const { return t < a.t; } }pt[M],que[NM],ss,now; int flag[N][N]; bool vis[N][N]; int dir[4][2] = {{-1,0},{0,-1},{0,1},{1,0}}; int n; bool isok(int x,int y) { return (x >= 0 && y >= 0 && x <= 400 && y <= 400); } int bfs() { ss.x = ss.y = ss.t = 0; int i,head,tail; head = tail = 0; que[tail ++] = ss; vis[0][0] = true; while(head != tail) { now = que[head ++]; if(head == NM) head = 0; if(flag[now.x][now.y] == inf) return now.t; ss = now; ss.t ++; for(i = 0;i < 4;i ++) { ss.x = now.x + dir[i][0]; ss.y = now.y + dir[i][1]; if(vis[ss.x][ss.y] || !isok(ss.x,ss.y)) continue; if(flag[ss.x][ss.y] == inf) return ss.t; if(ss.t < flag[ss.x][ss.y]) { vis[ss.x][ss.y] = true; que[tail ++] = ss; if(tail == NM) tail = 0; } } } return -1; } int main() { int i,j; while(scanf("%d",&n) != EOF) { memset(flag,0x3f,sizeof(flag)); memset(vis,false,sizeof(vis)); for(i = 0;i < n;i ++) { scanf("%d%d%d",&pt[i].x,&pt[i].y,&pt[i].t); flag[pt[i].x][pt[i].y] = min(flag[pt[i].x][pt[i].y],pt[i].t); for(j = 0;j < 4;j ++) { if(isok(pt[i].x + dir[j][0],pt[i].y + dir[j][1])) flag[pt[i].x + dir[j][0]][pt[i].y + dir[j][1]] = min(pt[i].t,flag[pt[i].x + dir[j][0]][pt[i].y + dir[j][1]]); } } printf("%d\n",bfs()); } return 0; }