POJ-3669 Meteor Shower

来源:互联网 发布:电商部门美工 编辑:程序博客网 时间:2024/06/10 17:41
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

题意
有流星将在不同的坐标降落,降落时间也不一样,Bessie一开始在(0,0)位置,Bessie准备逃跑,到一个永远不会被流星袭击到的地方,每走一步,时间加一。流星降落坐标(x,y),0<=x<=300,0<=y<=300,计算出Bessie到达不会被流星袭击的地方的最短时间,如果不能找到这个点,则输出-1。
题解
本题应该用广搜的思想来做,一开始把所有的点都是为安全点,然后就是要在输入的坐标中通过5个方向寻找出它能找到的所有坐标的最短爆炸时间,因为当一个
坐标发生爆炸时,它自己和它周围的4个点都会爆炸,所以从五个方向找,只有这样才可以正确的求解出来找到的每个坐标的最短爆炸时间,然后再进行广搜,和平常的广搜一样,如果找到安全点就退出,但是也需判断起始点是否安全,如果安全直接输出时间,在广搜时应注意在进行入队时从当前点到下一个点的所有时间应该小于下一个点的爆炸时间。

#include<stdio.h>#include<string.h>#include<queue>#include<stdlib.h>using namespace std;#define INF 0x3f3f3f3fint mapp[305][305],book[305][305],flag,n;                   //因为x,y小于等于300,所以数组应定义的大于300,防止爆炸影响int next1[5][2]= {0,1,0,-1,1,0,-1,0,0,0};                   //5个方向,因为也包括它自身若爆炸struct node{    int x;    int y;    int t;};void zang(int k,int w,int f)                                 //调用函数求流星飞来时坐标的最短爆炸时间{    int i,j,tx,ty;    for(i=0; i<5; i++)                                        //因为它本身以及周围的四个点都会爆炸,所以有五个方向    {        tx=k+next1[i][0];        ty=w+next1[i][1];        if(tx<0||ty<0)            continue;        if(mapp[tx][ty]==INF)                                  //如果找到的这个坐标当前是安全的,把爆炸时间赋给它            mapp[tx][ty]=f;        else            mapp[tx][ty]=min(f,mapp[tx][ty]);                  //如果已被更新过,则继续比较,求不同坐标的爆炸的最短时间    }}void bfs(int x,int y,int t)                                     //广搜{    int i,j;    queue<node>Q;    node now,tmp;    now.x=0;    now.y=0;    now.t=0;    Q.push(now);    while(!Q.empty())    {        now=Q.front();        Q.pop();        if(mapp[0][0]==INF)                                     //如果在初始位置是安全的话        {            flag=1;            printf("%d\n",now.t);            return ;        }        for(i=0; i<4; i++)                                       //向四个方向寻找,寻找到达安全点的最短时间        {            tmp.x=now.x+next1[i][0];            tmp.y=now.y+next1[i][1];            tmp.t=now.t+1;            if(tmp.x>=0&&tmp.y>=0&&tmp.x<=305&&tmp.y<=305)            {                if(mapp[tmp.x][tmp.y]==INF)                       //如果到达安全的点后                {                    flag=1;                    printf("%d\n",tmp.t);                    return ;                }                if(mapp[tmp.x][tmp.y]>tmp.t&&book[tmp.x][tmp.y]==0)   //如果在下一个地方没有发生爆炸                {                    book[tmp.x][tmp.y]=1;                    Q.push(tmp);                }            }        }    }}int main(){    while(~scanf("%d",&n))    {        int i,j,a,b,c;        flag=0;        for(i=0; i<=305; i++)            for(j=0; j<=305; j++)                mapp[i][j]=INF;                                       //定义所有的点都是安全的        for(i=0; i<n; i++)        {            scanf("%d%d%d",&a,&b,&c);            zang(a,b,c);                                             //函数调用        }        memset(book,0,sizeof(book));        book[0][0]=1;        bfs(0,0,0);                                                 //起始位置和时间        if(flag==0)            printf("-1\n");    }    return 0;}


原创粉丝点击