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.
104 lines
3.7 KiB
104 lines
3.7 KiB
/*
|
|
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;
|
|
}
|