1 条题解

  • 0

    题意分析

    给定一个M×NM \times N的网格地图,包含以下元素:

    • Y'Y':坦克的初始位置
    • T'T':目标位置
    • S'S':钢铁墙(不可穿过或破坏)
    • B'B':砖墙(可被射击破坏)
    • R'R':河流(不可穿过)
    • E'E':空地(可移动或射击)

    坦克每回合可选择:

    1. 向相邻44方向移动一步(目标需为E'E'T'T'
    2. 44方向之一射击(子弹直线飞行直至出界或击中墙体,击中B'B'则将其变为E'E'

    求从Y'Y'T'T'的最少回合数,无法到达输出1-1

    解题思路

    1. 状态建模:将坦克位置(x,y)(x,y)和地图状态(被破坏的B'B'墙)作为搜索状态
    2. 优先扩展:使用优先队列(按回合数stepstep排序)替代普通队列
    3. 射击处理
      • 子弹路径上遇到B'B'则立即破坏
      • 遇到S'S'R'R'则停止
    4. 移动限制:仅能移动到E'E'T'T'格子

    实现步骤

    1. 初始化
      • 记录Y'Y'T'T'的坐标
      • 将初始状态(Yx,Yy,0)(Y_x, Y_y, 0)加入优先队列
    2. 状态扩展
      • 移动:检查44方向相邻的E'E'T'T'格子
      • 射击:沿44方向模拟子弹路径,动态更新被破坏的B'B'
    3. 终止条件
      • 到达T'T'时返回当前stepstep
      • 队列为空时返回1-1

    代码实现

    #include<algorithm>
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<string>
    #include<queue>
    using namespace std;
    const int MAXN=300+10;
    struct node{
        int x,y,step;
        bool friend operator <(node a,node b){
            return a.step>b.step;
        }
    };
    char mp[MAXN][MAXN];
    int n,m,sx,sy,ex,ey;
    int vis[MAXN][MAXN];
    int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
    void BFS(){
        priority_queue<node> qu;
        memset(vis,0,sizeof(vis));
        node e1;
        e1.x=sx,e1.y=sy,e1.step=0;
        vis[e1.x][e1.y]=1;
        qu.push(e1);
        int ans=-1;
        while(!qu.empty()){
            node e2;
            e1=qu.top();qu.pop();
            if(e1.x==ex&&e1.y==ey){
                ans=e1.step;
                break;
            }
            for(int i=0;i<4;i++){
                e2.x=e1.x+dx[i];
                e2.y=e1.y+dy[i];
                if(!vis[e2.x][e2.y]&&e2.x>=0&&e2.x<n&&e2.y>=0&&e2.y<m&&mp[e2.x][e2.y]!='S'&&mp[e2.x][e2.y]!='R'){
                    if(mp[e2.x][e2.y]=='E'||mp[e2.x][e2.y]=='T') e2.step=e1.step+1;
                    else{//位置要保持不变,但step要+1
                        e2.step=e1.step+2;
                    }
                    vis[e2.x][e2.y]=1;
                    qu.push(e2);
                }
            }
        }
        printf("%d\n",ans);
    }
    int main(){
        while(~scanf("%d%d",&n,&m)&&n,m){
            for(int i=0;i<n;i++) scanf("%s",mp[i]);
            for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                    if(mp[i][j]=='Y'){ sx=i;sy=j; }
                    if(mp[i][j]=='T'){ ex=i;ey=j; }
                }
            }
            BFS();
        }
        return 0;
    }
    • 1

    信息

    ID
    1313
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者