HDU 3345 War Chess(bfs+优先队列)

本文介绍了一道编程题目,利用广度优先搜索(BFS)结合优先队列的方法来解决。任务是从起点出发,在一张地图上探索能够到达的位置,并考虑不同地形的能量消耗。文章提供了完整的代码实现。

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





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





题意:从起点开始向外走(上下左右)    开始时有一定的能量  进入不同的区域消耗不同的能量   能量为0不能继续行走    问可以停留在那些地方将这些地方标记为 " * "


"Y":  起点  不需要标记

".":  正常的格子  进入消耗1点能量

"T":  树  进入消耗2点能量

"R":  河 进入消耗3点能量

"#":  障碍  不能进入

"E"  敌人 不能进入 并且进入其附近(上下左右)的格子时会耗尽所有能量

"P"  朋友 进入消耗1点体力  但不能停留


输出标记后的地图 



相对简单的  bfs+优先队列


代码如下:

#include <stdio.h>
#include <cstring>
#include <queue> 
using namespace std;
char map[105][105];//         地图 
int count[105][105];//     转换为能量消耗地图 
int vis[105][105];
int N,M,X;
int x,y;
int dir[4][2]={1,0,0,1,0,-1,-1,0};


struct node{
    int x;int y;
    int step;
    friend bool operator < (node a,node b){
        return a.step<b.step;
    }
};
int judge0(int i,int j){
    if(i<0||j<0||i>=N||j>=M||vis[i][j]||map[i][j]=='#'||map[i][j]=='E')
        return 0;
    return 1;
}
int judge1(int i,int j){
    if(i<0||j<0||i>=N||j>=M)
        return 0;
    return 1;
}
int judge2(int i,int j){
    for (int k=0;k<4;k++){
        int a=i+dir[k][0];
        int b=j+dir[k][1];
        if (judge1(a,b)&&map[a][b]=='E'){
            return 1;
        }
    } 
    return 0;
}
void bfs(){
    priority_queue<node> Q;
    node n1,n2;
    n1.x=x;
    n1.y=y;
    n1.step=X;
    Q.push(n1);
    while (!Q.empty()){
        n2=Q.top();
        Q.pop();
        if (map[n2.x][n2.y]!='P'&&map[n2.x][n2.y]!='Y')
            map[n2.x][n2.y]='*';     
        for (int k=0;k<4;k++){
            int i=n2.x+dir[k][0];
            int j=n2.y+dir[k][1]; 
            if (judge0(i,j)){  
            	vis[i][j]=1;
                node next;
                next.x=i;
                next.y=j;
                if(n2.step>=count[i][j]){//         如果可以走到这一个区域(存在能量不足以走到这一区域的情况) 
                    next.step=n2.step-count[i][j];
                    if(judge2(i,j)){//            周围是否有敌人 
                        next.step=-1;
                    } 
                    if(next.step>=0||next.step==-1)
                    	Q.push(next);
                } 
               
            }
        }         
    }    
     
}
int main (){
    int t;
    scanf ("%d",&t);
    while (t--){    
        scanf ("%d%d%d",&N,&M,&X);
        getchar();
        memset(map,0,sizeof(map));
        for (int i=0;i<N;i++){
            scanf ("%s",map[i]);
        }
        for (int i=0;i<N;i++){
            for (int j=0;j<M;j++){
                if (map[i][j]=='Y'){//      记住起点 
                    x=i;
                    y=j;
                }
                //      进行能量的转换 
                if(map[i][j]=='.'||map[i][j]=='P')
                    count[i][j]=1;
                else if(map[i][j]=='T')
                    count[i][j]=2;
                else if (map[i][j]=='R')
                    count[i][j]=3;
            }
        }
        memset(vis,0,sizeof(vis));
        vis[x][y]=1;
        bfs();
        for (int i=0;i<N;i++){
            printf("%s\n",map[i]);
        }
        putchar('\n');    
    }
    return 0;
} 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值