1 条题解

  • 0
    @ 2026-2-17 22:16:56
    #include<bits/stdc++.h>
    using namespace std;
    
    // [1] 四个移动方向:上、下、左、右
    int dx[] = {-1, 1, 0, 0};
    int dy[] = {0, 0, -1, 1};
    
    // [2] BFS状态结构体:存储坐标、剩余血量、当前步数
    struct Node
    {
        int x, y;   // 当前坐标
        int hp;     // 剩余血量
        int step;   // 已走步数
    };
    
    int main()
    {
        int n, m;
        // [3] 读取地图大小n行m列
        cin >> n >> m;
        int mp[10][10];  // 地图数组,n,m≤9,预留足够空间
        int sx, sy, ex, ey; // 起点坐标(sx,sy)、终点坐标(ex,ey)
    
        // [4] 读取地图,同时定位起点和终点
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < m; j++)
            {
                cin >> mp[i][j];
                if(mp[i][j] == 2) // 起点
                {
                    sx = i;
                    sy = j;
                }
                if(mp[i][j] == 3) // 终点
                {
                    ex = i;
                    ey = j;
                }
            }
        }
    
        // [5] 访问标记数组:vis[x][y][hp] 表示坐标(x,y)、剩余血量hp的状态是否已访问
        // 血量范围0~6,共7种可能,因此第三维大小为7
        bool vis[10][10][7] = {false};
        queue<Node> q; // BFS队列
    
        // [6] 初始化起点状态:初始血量6,步数0,入队并标记访问
        q.push({sx, sy, 6, 0});
        vis[sx][sy][6] = true;
    
        // [7] BFS核心循环
        while(!q.empty())
        {
            // 取出队首状态
            Node cur = q.front();
            q.pop();
    
            // 遍历四个移动方向
            for(int i = 0; i < 4; i++)
            {
                // 计算移动后的新坐标
                int nx = cur.x + dx[i];
                int ny = cur.y + dy[i];
    
                // [8] 合法性校验1:坐标在地图范围内,且不是障碍物(0)
                if(nx < 0 || nx >= n || ny < 0 || ny >= m || mp[nx][ny] == 0)
                {
                    continue;
                }
    
                // [9] 移动一步,扣减血量
                int new_hp = cur.hp - 1;
                // 血量≤0直接死亡,跳过该方向
                if(new_hp <= 0)
                {
                    continue;
                }
    
                // [10] 到达终点,直接输出步数+1(当前步),BFS保证这是最短步数
                if(nx == ex && ny == ey)
                {
                    cout << cur.step + 1 << endl;
                    return 0;
                }
    
                // [11] 走到金币格(4),补满血量到6
                if(mp[nx][ny] == 4)
                {
                    new_hp = 6;
                }
    
                // [12] 该状态未访问过,标记访问并加入队列
                if(!vis[nx][ny][new_hp])
                {
                    vis[nx][ny][new_hp] = true;
                    q.push({nx, ny, new_hp, cur.step + 1});
                }
            }
        }
    
        // [13] 队列遍历完毕仍未到达终点,无法回家,输出-1
        cout << -1 << endl;
        return 0;
    }
    
    • 1

    信息

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