华为OD机试题库《C++》限时优惠 9.9
华为OD机试题库《Python》限时优惠 9.9
华为OD机试题库《JavaScript》限时优惠 9.9
针对刷题难,效率慢,我们提供一对一算法辅导, 针对个人情况定制化的提高计划(全称1V1效率更高)。
看不懂有疑问需要答疑辅导欢迎私VX: code5bug
题目描述
有一个局部互联区域内的 n 台设备,每台设备都有一定数量的空闲资源,这些资源可以池化共享。用户会发起两种操作:
- 申请资源:输入
1 x
,表示本次申请需要 x 个资源。系统要返回当前资源池中能满足此申请且剩余资源最少的设备 ID;如果有多台设备满足条件,返回设备 ID 最小的;如果没有任何设备能满足,返回0
并不做任何分配。 - 释放资源:输入
2 y
,表示将第 y 次申请(不一定是成功分配的那一次)释放回原设备。释放时,资源立即归还,且空闲资源自动连续,无需考虑空洞。
给定 n(1 ≤ n ≤ 1000)、操作次数 m(1 ≤ m ≤ 105),以及初始时每台设备的空闲资源数 d₁…dₙ(1 ≤ dᵢ ≤ 1000),以及接下来 m 行操作,输出每次 “申请” 操作的返回值。
输入描述
第一行,输入n和 m
第二行输入n台设备的初始空闲资源数
接下来m行,输出要执行的操作
输出描述
输出每次“申请”操作的返回值。
示例1
输入:
2 2
100 500
1 40
1 450
输出:
1 2
题解
这道题目属于 模拟题,主要考察对操作流程的模拟和数据结构的选择。需要处理两种操作:申请资源和释放资源,并根据特定规则返回结果。
解题思路
- 申请资源操作(
1 x
):
- 遍历所有设备,筛选出当前空闲资源大于
x
的设备。- 对这些设备按照剩余资源升序排序,如果剩余资源相同,则按照设备 ID 升序排序。
- 如果找到满足条件的设备,选择剩余资源最少且 ID 最小的设备,分配资源,并记录分配历史。
- 如果没有满足条件的设备,返回
0
。- 释放资源操作(
2 y
):
- 根据历史记录找到第
y
次申请对应的设备和分配的资源量。- 将资源归还给原设备。
代码描述
- 输入处理:读取设备数量
n
和操作次数m
,以及每台设备的初始空闲资源。- 操作处理:
- 对于申请操作,筛选并排序可用设备,分配资源并记录历史。
- 对于释放操作,根据历史记录归还资源。
- 输出结果:每次申请操作的返回值。
时间复杂度
- 申请操作:每次申请需要遍历所有设备(O(n)),然后排序(O(n log n)),因此最坏情况下为 O(n log n)。
- 释放操作:直接根据历史记录归还资源,O(1)。
- 总时间复杂度:O(m * n log n),其中
m
是操作次数,n
是设备数量。空间复杂度
- 需要存储设备空闲资源数组(O(n))和历史记录(O(m))。
- 总空间复杂度:O(n + m)。
C++
// Author: code5bug
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m;
cin >> n >> m; // 设备数量,操作次数
vector<int> free(n); // 每台设备的空闲资源数
for (int i = 0; i < n; i++) {
cin >> free[i];
}
// 历史记录:保存每次申请的设备索引和分配的资源量
vector<pair<int, int>> history;
// 保存每次申请操作的返回值
vector<int> result;
for (int i = 0; i < m; i++) {
int type, v;
cin >> type >> v; // 操作类型和参数
// 申请资源操作
if (type == 1) {
// 筛选出空闲资源足够的设备
vector<pair<int, int>> tmp;
for (int j = 0; j < n; j++) {
if (free[j] >= v) {
tmp.emplace_back(free[j], j);
}
}
// 按剩余资源升序排序,若相同则按设备ID升序排序
sort(tmp.begin(), tmp.end(), [](const pair<int, int>& a, const pair<int, int>& b) {
return a.first != b.first ? a.first < b.first : a.second < b.second;
});
if (!tmp.empty()) {
int idx = tmp[0].second; // 选择剩余资源最少且ID最小的设备
free[idx] -= v; // 分配资源
history.emplace_back(idx, v);
result.push_back(idx + 1); // 设备ID从1开始
} else {
// 没有设备满足条件
history.emplace_back(-1, 0);
result.push_back(0);
}
}
// 释放资源操作
else if (type == 2) {
auto [idx, size] = history[v - 1]; // 获取第v次申请的历史记录
if (idx != -1) {
free[idx] += size; // 归还资源
}
}
}
// 输出结果
for (int res : result) {
cout << res << " ";
}
return 0;
}
希望这个专栏能让您熟练掌握算法, 🎁🎁🎁。
整理题解不易, 如果有帮助到您,请给点个赞 ❤️ 和收藏 ⭐,让更多的人看到。🙏🙏🙏