大厂笔试题
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

/*
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;
}