1 条题解
-
0
#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
- 上传者