HDU3533Escape(BFS )

本文探讨了一种从(0,0)到(n,m)点的路径规划算法,考虑到有限的能量和地图上的敌军炮台威胁。算法通过三维数组标记状态,并利用BFS(广度优先搜索)解决复杂环境下的路径寻找问题,同时考虑了炮台的射击方向、周期和速度等因素,确保在有限步数内安全到达终点。通过实例输入输出解析,深入理解算法实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:要从(0,0)到(n,m)点,有四个移动的方向,初始时有一个能量,走一步消耗一个单位,能量为0还没到就是失败,同时,地图上有敌军的炮台,告诉你炮台的射击方向,这个方向是固定的,以及它每隔t秒朝该方向发射一个速度是v的炮弹,然后是炮台的坐标,
1.炮台可以挡住子弹,而不会被摧毁
2.炮弹对人的伤害只有人和炮弹在格点相遇
3.人物可以选择在某一个点停留一段时间
输入:
n,m,k,d(n*m的图,k组数据,人物初始能量d)
direction t v x y(方向,周期,速度,坐标)
输出 :最小到达的步数,否则 -1
其实就是一般的图的BFS,每一步的状态有三个(x,y,step)
用三维的数组标志。比较麻烦的是判断某一个点,在某个时刻是否会有炮弹。

#include<bits/stdc++.h>
#define cl(a,b) memset(a,b,sizeof(a));
#define LL long long
#define out(x) cout<<x<<endl;
using namespace std;
const int maxn=105;
const int inf=9999999;

int n,m,k,d;
int dir[][2]={{0,1},{1,0},{-1,0},{0,-1},{0,0}};///对应的四个方向是ESNW,(0,0)表示在原地
struct castle{//炮台
    char dir;
    int t,v;
    void clear(){
        dir='*';t=v=0;
    }
    castle(){}
    castle(char dir,int t,int v){
        this->dir=dir;this->t=t;this->v=v;
    }
}castles[maxn][maxn];
bool vis[1005][maxn][maxn];//用int会超内存,int是4字节,bool是一个字节
struct node{//搜索的状态节点
    int x,y,step;
    node(){};
    node(int x,int y,int step){
        this->x=x;this->y=y;this->step=step;
    }
    bool operator<(const node& tt) const{
        return step>tt.step;
    }
};
bool pan(node s){
    if(s.x>=0&&s.x<=n&&s.y>=0&&s.y<=m)return true;
    return false;
}
bool isEnable(node s){///四个方向找最近的城堡,找出这个时刻这个位置是否有子弹。

    //printf("%d %d\n",s.x,s.y);
    if(castles[s.x][s.y].dir!='*')return false;
    ///-->E,表示往右看有没有炮台,有的话取第一个
    node tmp=s;
    castle cs;
    int time=s.step;
    while(pan(tmp)&&castles[tmp.x][tmp.y].dir=='*'){
        tmp.x+=dir[0][0];
        tmp.y+=dir[0][1];
    }
    if(pan(tmp))cs=castles[tmp.x][tmp.y];
    if(pan(tmp)&&cs.dir=='W'){
        int dis=tmp.y-s.y;
        if(dis%cs.v==0){
            if((time-dis/cs.v)>=0&&(time-dis/cs.v)%cs.t==0)
                return false;
        }
    }
    ///-->S
    tmp=s;
    while(pan(tmp)&&castles[tmp.x][tmp.y].dir=='*'){
        tmp.x+=dir[1][0];
        tmp.y+=dir[1][1];
    }
    if(pan(tmp))cs=castles[tmp.x][tmp.y];
    if(pan(tmp)&&cs.dir=='N'){
        int dis=tmp.x-s.x;
        if(dis%cs.v==0){
            if((time-dis/cs.v)>=0&&(time-dis/cs.v)%cs.t==0){
                return false;
            }
        }
    }
    ///-->N
    tmp=s;
    while(pan(tmp)&&castles[tmp.x][tmp.y].dir=='*'){
        tmp.x+=dir[2][0];
        tmp.y+=dir[2][1];
    }
    if(pan(tmp))cs=castles[tmp.x][tmp.y];
    if(pan(tmp)&&cs.dir=='S'){
        int dis=s.x-tmp.x;
        if(dis%cs.v==0){
            if((time-dis/cs.v)>=0&&(time-dis/cs.v)%cs.t==0){
                return false;
            }
        }
    }
    ///-->W
    tmp=s;
    while(pan(tmp)&&castles[tmp.x][tmp.y].dir=='*'){
        tmp.x+=dir[3][0];
        tmp.y+=dir[3][1];
    }
    if(pan(tmp))cs=castles[tmp.x][tmp.y];
    if(pan(tmp)&&cs.dir=='E'){
        int dis=s.y-tmp.y;
        if(dis%cs.v==0){
            if((time-dis/cs.v)>=0&&(time-dis/cs.v)%cs.t==0){
                return false;
            }
        }
    }
    return true;
}

int bfs(){
    cl(vis,false);
    priority_queue<node> q;
    q.push(node(0,0,0));
    vis[0][0][0]=true;
    while(!q.empty()){
        node s=q.top();q.pop();
        for(int i=0;i<5;i++){
            node tmp=s;
            tmp.x+=dir[i][0];
            tmp.y+=dir[i][1];
            tmp.step++;
            if(tmp.x==n&&tmp.y==m){
                if(castles[n][m].dir=='*')return tmp.step;
                else return -1;
            }
            if(tmp.step>d)return -1;
            if(pan(tmp)&&!vis[tmp.step][tmp.x][tmp.y]){
                if(isEnable(tmp)){
                    vis[tmp.step][tmp.x][tmp.y]=true;
                    q.push(tmp);
                }
            }
        }
    }
    return -1;
}
int main(){
    while(~scanf("%d%d%d%d",&n,&m,&k,&d)){

        for(int i=0;i<=n;i++){
            for(int j=0;j<=m;j++){
                castles[i][j].clear();
            }
        }

        for(int i=0;i<k;i++){
            char c[2];
            int t,v,x,y;
            scanf("%s%d%d%d%d",c,&t,&v,&x,&y);
            castles[x][y]=castle(c[0],t,v);
        }
        int ans=bfs();
        if(ans==-1){
            puts("Bad luck!");
        }
        else {
            printf("%d\n",ans);
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值