You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*
c++实现以下问题: 有一个 N x N 大小的迷宫。初始状态下,配送员位于迷宫的左上角,他希望前往迷宫的右下角。配送员只能沿若上下左右四个方向移动,从每个格子移动到相邻格子所需要的时间是 1个单位,他必须用最多 K 个(也可以少于 K 个)单位时间到达右下角格子。迷宫的每个格子都有辐射值,配送员必须穿着防护能力不低于相应辐射值的防护服,才能通过该格子。他希望知道,防护服的防护能力最少要达到多少,他才能顺利完成任务。注意:配送员需要通过迷宫的左上角和右下角,因此防护服的防护能力必须大于等于这两个格子的辐射值。 解答要求: 时间限制: C/C++1000ms,其他语言:2000ms内存限制: C/C++256MB,其他语言:512MB 输入: 前两行各包含一个正整数,分别对应 N 和 K后 N 行各包含 N 整数,以空格分隔,表示地图上每个位置的辐射值,2≤N≤100。 K≥2N-2,以保证题目有解。所有辐射值都是非负整数,绝对值不超过 1e4 输出: 一个整数,表示配送员穿着防护服的最低防护能力。
样例1 输入: 2 2 1 3 2 1 输出:2 解释:配送员可以选择通过左下角(辐射值为2)的路线,耗费2单位时间。
样例2 输入: 5 12 0 0 0 0 0 9 9 3 9 0 0 0 0 0 0 0 9 5 9 9 0 0 0 0 0 输出:3 解释:最优路线:往右2格,往下2格,往左2格,往下2格,往右4格,耗费12单位时间,经过格子的最大辐射值为3。 另外,在地图不变的情况下,如果K=16,输出为0;如果K=8,输出为5。
*/ #include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std; const int INF = 1e9; // 定义一个足够大的值表示不可达
int N, K; vector<vector<int>> radiation; // 四个方向的移动
int dx[] = {1, -1, 0, 0}; int dy[] = {0, 0, 1, -1}; // 判断是否可以在指定的防护能力下从 (0,0) 到 (N-1,N-1)
bool canReach(int limit) { if (radiation[0][0] > limit || radiation[N-1][N-1] > limit) { return false; } vector<vector<bool>> visited(N, vector<bool>(N, false)); queue<pair<int, int>> q; q.push({0, 0}); visited[0][0] = true; int time = 0; while (!q.empty()) { int qsize = q.size(); if (time > K) return false; // 时间超过 K
while (qsize--) { int x = q.front().first; int y = q.front().second; q.pop(); if (x == N-1 && y == N-1) { return true; // 成功到达终点
} for (int i = 0; i < 4; ++i) { int nx = x + dx[i]; int ny = y + dy[i]; if (nx >= 0 && nx < N && ny >= 0 && ny < N && !visited[nx][ny] && radiation[nx][ny] <= limit) { visited[nx][ny] = true; q.push({nx, ny}); } } } ++time; // 每次扩展一层,时间增加
} return false; // 没有在 K 时间内到达终点
}
int main() { // 读入 N 和 K
cin >> N >> K; radiation.resize(N, vector<int>(N)); // 读入迷宫的辐射值
for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { cin >> radiation[i][j]; } } // 二分查找防护能力
int low = 0, high = 1e4, ans = INF; while (low <= high) { int mid = (low + high) / 2; if (canReach(mid)) { ans = mid; high = mid - 1; } else { low = mid + 1; } } // 输出结果
cout << ans << endl; return 0; }
|