poj 3669 Meteor Shower

Meteor Shower
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 12425   Accepted: 3360

Description

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 (XiYi) (0 ≤ X≤ 300; 0 ≤ Y≤ 300) at timeTi (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: XiYi, 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

写的简直要跪的一道题啊,,思路倒是慢慢想清楚了,,最后再结构体实现上却卡了很久,,关键是是对队列和bfs使用还不熟
现在的水平就好好分析下别人的代码吧,,
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define inf  0x3f3f3f3f
int map[305][305],maxn;
int dx[5]={0,0,0,1,-1},dy[5]={0,1,-1,0,0};//刚开始初始化为4个,没有加上本身的x,y位置
                        //后来还是发现同时给包括自己在内的五个区域赋值方便
struct  Node{
   int step;
   int x,y;
}node;       //直接定义结构体就好,,,,刚开始还开了node[900001],,,对队列使用不熟悉
int  ok(int x,int y)
{
     if(x>=0&&x<=305&&y>=0&&y<=305)
        return 1;
     return 0;
}
int  bfs()
{
    queue<Node> q;
    Node s0;
    s0.x=s0.y=s0.step=0;
    q.push(s0);
    while(q.size())
    {
        Node p=q.front();
        q.pop();
        if(map[p.x][p.y]==0x3f3f3f3f)
            return p.step;//没有流星,,安全区
        for(int i=0;i<=4;i++)
        {
            Node next;
            next.x=p.x+dx[i];
            next.y=p.y+dy[i];
            next.step=p.step+1;
            if(!ok(next.x,next.y))
                 continue;
            if(map[next.x][next.y]==inf)
                 return next.step;
            if(next.step>=map[next.x][next.y])
                 continue; //这段代码看别人的,,非常非常佩服,,因为刚开始发现还要处理
       //不能重新访问已经访问过的点这一问题,,后来发现  该段代码一方面可以保证在流星来临前才进入
        //另一方面可以保证不再访问已经访问过的点,因为next.step<map[i][j]=cur.step;;
        //核心思想是map数组一方面记录人的时间(步数),一方面记录流星到达的时间 
            else
            {
                 if(next.step<map[next.x][next.y])
                    map[next.x][next.y]=next.step;  //与上面 对应,,对访问过的点其值设为
                                  //到达的时间,,避免再次访问
                 q.push(next);//直接压入结构体就好
            }
        }
    }
    return -1;
}
int main()
{
     int n;
     while(~scanf("%d",&n))
     {
         int x,y,t;
         memset(map,0x3f,sizeof(map));//memset只能初始化为0或者-1,,因为memset只能一个字节
                        //一个字节的赋值,int四个字节,所以最后map数组就是0x3f3f3f3f
         for(int  i=1;i<=n;i++)
         {
             scanf("%d %d %d",&x,&y,&t);
             for(int i=0;i<=4;i++)
             {
                 int kx=x+dx[i];
                 int ky=y+dy[i];
                 if(ok(kx,ky)&&map[kx][ky]>t)
                  map[kx][ky]=t;
             }
         }
            printf("%d\n",bfs());
     }
     return 0;
}
posted @ 2015-11-28 18:36  快点说我帅  阅读(83)  评论(0编辑  收藏  举报