zoukankan      html  css  js  c++  java
  • 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();
        }
    }
    

      

    人生如修仙,岂是一日间。何时登临顶,上善若水前。
  • 相关阅读:
    ListView Item 里多种点击事件的用法
    dialog 设置maxHeight 最大高度
    php的json_encode不兼容JSON_UNESCAPED_UNICODE的解决方案
    java面试一定会遇到的56个面试题
    使用LinearLayout实现ListView,解决ListView和ScrollView滚动冲突
    检测是否是小米手机
    Android 自定义ViewGroup 实战篇 -> 实现FlowLayout
    clone分支,修改文件本地commit后, push回原分支失败,处理方法
    SQL语句往Oracle数据库中插入日期型数据(to_date的用法)
    C# TimeSpan 计算时间差(时间间隔)
  • 原文地址:https://www.cnblogs.com/f-society/p/6821764.html
Copyright © 2011-2022 走看看