POJ3669 Meteor Shower

来源:互联网 发布:ubuntu 声音图标 灰色 编辑:程序博客网 时间:2024/05/29 18:59

Bessie hears that an extraordinary meteor shower is coming; reports say that these meteors will crash into earth and destroy anything they hit. Anxious for her safety, she vows to find her way to a safe location (one that is never destroyed by a meteor) . She is currently grazing at the origin in the coordinate plane and wants to move to a new, safer location while avoiding being destroyed by meteors along her way.

The reports say that M meteors (1 ≤ M ≤ 50,000) will strike, with meteor i will striking point (Xi, Yi) (0 ≤ Xi ≤ 300; 0 ≤ Yi ≤ 300) at time Ti (0 ≤ Ti ≤ 1,000). Each meteor destroys the point that it strikes and also the four rectilinearly adjacent lattice points.

Bessie leaves the origin at time 0 and can travel in the first quadrant and parallel to the axes at the rate of one distance unit per second to any of the (often 4) adjacent rectilinear points that are not yet destroyed by a meteor. She cannot be located on a point at any time greater than or equal to the time it is destroyed).

Determine the minimum time it takes Bessie to get to a safe place.

Input
* Line 1: A single integer: M
* Lines 2..M+1: Line i+1 contains three space-separated integers: Xi, Yi, and Ti

Output
* Line 1: The minimum time it takes Bessie to get to a safe place or -1 if it is impossible.

Sample Input
4
0 0 2
2 1 2
1 1 2
0 3 5
Sample Output
5

题意:流星雨来临。此时贝丝站在(0,0)起点。给出n个流星的信息x,y,t。x,y表示流星降落的坐标,t表示流星降落到地面的时刻。被流星砸过的地面不可再走。问贝丝在多短的时间内可以走到地图上安全的地点(即不被流星砸到,该点流星降落的时刻b[x][y]==INF)。另:当贝丝在起点时就被砸到则同样到达不了安全地点。如果到达不了则输出-1。

解题思路:bfs。题目多出时间的限制。首先将每一个格子流星降落的时刻用一个b数组记录,走过的状态用book数组记录。“被流星砸过的地面不可再走。”可转化为当此时到达该格子的时间(Q[head].t)大于(b[tx][ty])即不再扩展到那一格。在搜索前将地图的降落时间数组b初始化(即change函数)。搜索限制条件多一条判断时间。

AC代码:

#include<stdio.h>#include<string.h>#include<algorithm>#define INF 0x3f3f3f3f//必须初始化INF不知道为什么不能直接用0x3f替代 using namespace std;int book[350][350],b[350][350],nx[5][2]={0,0,0,-1,1,0,0,1,-1,0};//那一个点和周围四个点 struct node{    int x,y,t;}Q[160000];void change(int x,int y,int t)//初始化b数组{    for(int i=0;i<5;i++)    {        int tx=x+nx[i][0];        int ty=y+nx[i][1];        if(tx>=0&&ty>=0)            b[tx][ty]=min(b[tx][ty],t);    }}//将流星落下的时刻记录在b数组内 void bfs(){    int head=1,tail=2,tx,ty;    Q[head].x=0;    Q[head].y=0;    Q[head].t=0;    while(head<tail)    {        for(int i=0;i<5;i++)        {            int tx=Q[head].x+nx[i][0];            int ty=Q[head].y+nx[i][1];            if(book[tx][ty]==0&&tx>=0&&ty>=0&&(b[tx][ty]==INF||Q[head].t+1<b[tx][ty]))//如果下一步流星永远砸不到或者会砸到但是是下一步之后砸到             {                Q[tail].x=tx;                Q[tail].y=ty;                Q[tail].t=Q[head].t+1;                book[tx][ty]=1;                if(b[tx][ty]==INF)//找到一个永远不被砸到的点                 {                    printf("%d\n",Q[tail].t);                    return;                }                tail++;            }        }        head++;    }    printf("-1\n");//找不到则输出-1 }int main(){    int n,x,y,t;    while(~scanf("%d",&n))    {        memset(book,0,sizeof(book));        memset(b,INF,sizeof(b));//初始化每个点流星都砸不到         for(int i=0;i<n;i++)        {            scanf("%d%d%d",&x,&y,&t);            change(x,y,t);//将流星砸到的点的状态更新         }        if(b[0][0]==0)        {            printf("-1\n");//如果一开始就被砸到             continue;        }        bfs();    }    return 0;}
原创粉丝点击