poj 3669 bfs(这道题隐藏着一个大坑)

Posted 北溟有鱼。

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 3669 bfs(这道题隐藏着一个大坑)相关的知识,希望对你有一定的参考价值。

题意

在x,y坐标系,有流星会落下来,给出每颗流星落下来的坐标和时间,问你能否从(0,0)这个点到一个安全的位置。所谓的安全位置就是不会有流星落下的位置。

题解:

广搜,但是这里有一个深坑,就是搜索的时候判断坐标是否越界的时候,题中说0≤x≤300,0≤y≤300。也就是说如果 if(x>300||y>300||x<0||y<0) 就是越界,不用进队列。

注意,就是这个 x>300||y>300 越界条件有问题。不能是300,要比300大,哪怕301也行。

下面看我调试了5个小时的AC代码,才发现这个神坑...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

const int MAX=305;

typedef struct node
{
    node()
    {
        x=y=time=0;
    }
    int x,y;
    int time;
}Node;

int mmap[MAX][MAX];    //地图
int dx[4]={-1,1,0,0};  //方向控制
int dy[4]={0,0,-1,1};
int flag[MAX][MAX];    //标记位

queue<Node> q;

void bfs()
{
    memset(flag,0,sizeof(flag));
    while(!q.empty()) q.pop();

    Node s;   //把原点入队
    s.x=0;
    s.y=0;
    s.time=0;
    q.push(s);
    flag[0][0]=1;

    Node now;
    while(!q.empty())
    {
        Node cur=q.front();
        q.pop();
        for(int i=0;i<4;i++)
        {
            int xx=cur.x+dx[i];
            int yy=cur.y+dy[i];
            if(xx<0||yy<0||xx>301||yy>301)    //就是这里,妈的可坑了,题意明明说<=300,也就是说>300不行,他妈的非要>301才能过,那不就是<=301了?
                continue;
            now.x=xx;
            now.y=yy;
            now.time=cur.time+1;
            if(mmap[now.x][now.y]==-1)     //找到安全地点
            {
                cout<<now.time<<endl;
                return;
            }
            if(flag[now.x][now.y]==0)     //如果没有被走过
            {
                if(now.time<mmap[now.x][now.y]||mmap[now.x][now.y]==-1)  //如果当前地点是安全地点或者还没有被流星炸毁
                {
                    flag[now.x][now.y]=1;
                    q.push(now);
                }
            }
        }
    }
    cout<<-1<<endl;
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(mmap,-1,sizeof(mmap));   //地图初始化为-1
        for(int i=0; i<n; i++)        //输入地图信息
        {
            int x,y,t;
            scanf("%d%d%d",&x,&y,&t);
            if(mmap[x][y]!=-1)                    //但要注意的是如果当前流星的坠地时间大于以前的流星的坠地时间,要取最小值
                mmap[x][y]=min(mmap[x][y],t);
            else
                mmap[x][y]=t;
            for(int i=0;i<4;i++)
            {
                int xx=x+dx[i];
                int yy=y+dy[i];
                if(xx<0||yy<0||xx>301||yy>301)   //还有这里也是
                    continue;
                if(mmap[xx][yy]!=-1)           //这个也是,要取最小坠地时间
                    mmap[xx][yy]=min(mmap[xx][yy],t);
                else mmap[xx][yy]=t;
            }
        }
        if(mmap[0][0]==0)         //如果在原点就被炸
            cout<<-1<<endl;
        else
            bfs();
    }
}

  

 

以上是关于poj 3669 bfs(这道题隐藏着一个大坑)的主要内容,如果未能解决你的问题,请参考以下文章

POJ3669解题报告(bfs)

POJ 3669 Meteor Shower(BFS)

POJ - 3669Meteor Shower(bfs)

使用VS调试高效修改代码(poj 3984为例)

POJ 3414 (BFS)

POJ 3278 Catch That Cow(BFS 剪枝)