HDU3533(Escape)

不愧是kuangbin的搜索進階,這題沒靈感寫起來好心酸php

思路是預處理全部炮臺射出的子彈,以此構造一個三維圖(其中一維是時間)node

預處理過程就至關於在圖中增長了不少不可到達的牆,而後就是一個簡單的bfsios

此題難點也是預處理過程,還有就是注意能夠停在原地也就是有5個方向spa

而後就是建圖用bool類型,否則可能會爆內存。code

 

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

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!\n");
        else printf("%d\n",ans);
    }
    return 0;
}

努力向高級搜索邁進!ci

相關文章
相關標籤/搜索