1 条题解
-
0
#include<bits/stdc++.h> using namespace std; // 棋盘最大尺寸,适配n,m≤1000的要求 const int MAXN = 1005; // 四个移动方向:上、下、左、右 int dx[] = {-1, 1, 0, 0}; int dy[] = {0, 0, -1, 1}; int a[MAXN][MAXN]; // 存储每个房间的伤害值 int vis[MAXN][MAXN]; // 访问标记数组,用时间戳避免每次重置 int tim = 0; // 时间戳,用于标记当前BFS的访问状态 int n, m; // 迷阵的行数n、列数m // 验证函数:判断伤害上限为mid时,是否存在可行路径 bool check(int mid) { tim++; // 时间戳+1,区分不同次BFS的访问标记 queue<pair<int, int>> q; // 多源BFS初始化:第一行所有入口都作为起点入队 for(int j = 1; j <= m; j++) { if(a[1][j] <= mid) // 第一行伤害为0,必然满足条件 { vis[1][j] = tim; q.push({1, j}); } } // BFS核心循环 while(!q.empty()) { auto [x, y] = q.front(); q.pop(); // 到达第n行,直接返回可行 if(x == n) { return true; } // 遍历四个移动方向 for(int i = 0; i < 4; i++) { int nx = x + dx[i]; int ny = y + dy[i]; // 合法性校验: // 1. 坐标在迷阵范围内 // 2. 该格子未被当前BFS访问过 // 3. 该格子的伤害值≤当前上限mid if(nx >= 1 && nx <= n && ny >= 1 && ny <= m && vis[nx][ny] != tim && a[nx][ny] <= mid) { vis[nx][ny] = tim; q.push({nx, ny}); // 提前判断:到达第n行直接返回,无需继续遍历 if(nx == n) { return true; } } } } // 遍历完所有可达格子仍未到达第n行,不可行 return false; } int main() { // 关闭cin同步,加速输入输出 ios::sync_with_stdio(false); cin.tie(nullptr); // 读取迷阵大小 cin >> n >> m; // 读取每个房间的伤害值,使用1-based坐标和题目对应 for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { cin >> a[i][j]; } } // 二分答案核心循环 int left = 0, right = 1000; // 伤害值最大为1000,右边界设为1000 int ans = 1000; // 记录最终答案 while(left <= right) { int mid = (left + right) / 2; if(check(mid)) { // 当前mid可行,尝试寻找更小的可行值 ans = mid; right = mid - 1; } else { // 当前mid不可行,需要增大上限 left = mid + 1; } } // 输出最小伤害代价 cout << ans << '\n'; return 0; }
- 1
信息
- ID
- 1304
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者