zoukankan      html  css  js  c++  java
  • HDU3533(Escape)

    不愧是kuangbin的搜索进阶,这题没灵感写起来好心酸

    思路是预处理所有炮台射出的子弹,以此构造一个三维图(其中一维是时间)

    预处理过程就相当于在图中增加了很多不可到达的墙,然后就是一个简单的bfs

    此题难点也是预处理过程,还有就是注意可以停在原地也就是有5个方向

    然后就是建图用bool类型,不然可能会爆内存。

    http://acm.hdu.edu.cn/showproblem.php?pid=3533

    AC: 405ms 11608kb

    #include<iostream>
    #include<sstream>
    #include<stack>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<climits>
    #include<cctype>
    #include<queue>
    #include<algorithm>
    #include<cmath>
    #include<map>
    #include<set>
    #define inf 0x3f3f3f3f
    #define N 150
    
    using namespace std;
    
    int n,m,ans,energe;          //energe所给的总时间
    int dir[5][2]= {{-1,0},{0,-1},{1,0},{0,1},{0,0}};   //(0,0)留在原地
    bool pic[101][101][1001];
    struct GUN{
        short int x,y;
        short int dir;          //炮台方向
        short int period;       //炮台发射子弹的周期
        short int velocity;     //子弹速度
    } gun[101];
    struct NODE{
        short int x,y;
        short int eng;      //当前所耗时间
    }node,temp;
    
    void init(int &group)   //预处理(参考HUSToj上ID为ENDIF的代码)
    {
        for(int i=0; i<group; ++i)
        {
            int state=0;    //子弹走过的路程
            int x=gun[i].x;int y=gun[i].y;
            int dd=gun[i].dir;
            while(1)
            {
                ++state;
                x+=dir[dd][0];y+=dir[dd][1];
                if(x<0||x>n||y<0||y>m||(!pic[x][y][0])) break;   //有炮台,子弹会被阻挡
                if(!(state%gun[i].velocity))        //如果子弹在整数时间内到达某可达位置
                {                                   //则进行图的预处理(增加不可到达的“墙”)
                    for(int j=state/gun[i].velocity; j<=energe; j+=gun[i].period)
                        pic[x][y][j]=false;
                }
            }
        }
    }
    
    bool bfs()
    {
        queue<NODE>q;
        node.x=0; node.y=0;
        node.eng=0;
        q.push(node);
        while(!q.empty())
        {
            node=q.front(); q.pop();
            if(node.x==n&&node.y==m)
            {
                ans=node.eng;
                return true;
            }
            if(node.eng==energe) return false;
            if(n-node.x+m-node.y>energe-node.eng) continue;   //曼哈顿距离剪枝
            temp=node;
            ++temp.eng;
            for(int i=0; i<5; ++i)
            {
                temp.x=node.x+dir[i][0];
                temp.y=node.y+dir[i][1];
                if(temp.x<0||temp.x>n||temp.y<0||temp.y>m||(!pic[temp.x][temp.y][temp.eng]))
                    continue;
                pic[temp.x][temp.y][temp.eng]=false;
                q.push(temp);
            }
        }
        return false;
    }
    
    int main()
    {
        //freopen("lxx.txt","r",stdin);
        int group;
        char ch;
        while(scanf("%d%d%d%d",&n,&m,&group,&energe)!=EOF)
        {
            memset(pic,true,sizeof(pic));
            for(int i=0; i<group; ++i)
            {
                scanf(" %c",&ch);
                if(ch=='N') gun[i].dir=0;
                else if(ch=='W') gun[i].dir=1;
                else if(ch=='S') gun[i].dir=2;
                else gun[i].dir=3;
                scanf("%hd%hd%hd%hd",&gun[i].period,&gun[i].velocity,&gun[i].x,&gun[i].y);
                for(int j=0; j<=energe; ++j)
                    pic[gun[i].x][gun[i].y][j]=false;
            }
            init(group);
            if(!bfs()) printf("Bad luck!
    ");
            else printf("%d
    ",ans);
        }
        return 0;
    }

    努力向高级搜索迈进!

  • 相关阅读:
    讯飞语音合成 简单使用
    android UI 操作 不要在子线程中操作UI
    把信送给加西亚
    android 二维码 扫描,生成,竖屏
    Android App签名(为apk签名)
    android 蓝牙 通信 bluetooth
    Android 蓝牙开发基本流程
    Android 使用 Application 简单介绍
    几个比较特殊的目录
    FHS目录配置下,常见的几个问题及解答
  • 原文地址:https://www.cnblogs.com/Kurokey/p/5210813.html
Copyright © 2011-2022 走看看