华为OD机试 2024E卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
有一个总空间为100字节的堆,现要从中新申请一块内存,内存分配原则为:
优先分配紧接着前一块已使用的内存,分配空间足够时分配最接近申请大小的空闲内存。
二、输入描述
第1行是1个整数,表示期望申请的内存字节数。
第2到第N行是用空格分割的两个整数,表示当前已分配的内存的情况,每一行表示一块已分配的连续内存空间,每行的第1个和第2个整数分别表示偏移地址和内存块大小,如: 0 1 3 2 表示0偏移地址开始的1个字节和3偏移地址开始的2个字节已被分配,其余内存空闲。
三、输出描述
若申请成功,输出申请到内存的偏移 若申请失败,输出-1。
备注:
- 若输入信息不合法或无效,则申请失败
- 若没有足够的空间供分配,则申请失败
- 堆内存信息有区域重叠或有非法值等都是无效输入
四、测试用例
1、输入
1 2
0 1
3 2
2、输出
1
3、说明
堆中已使用的两块内存是偏移从0开始的1字节和偏移从3开始的2字节,空闲的两块内存是偏移从1开始2个字节和偏移从5开始95字节根据分配原则,新申请的内存应从1开始分配1个字节,所以输出偏移为1。
五、解题思路
- 输入解析:
- 第一行输入是期望申请的内存字节数。
- 后续输入是已分配的内存块,用偏移地址和大小表示。
- 检查输入合法性:
- 确保输入的内存块不重叠且偏移和大小均为有效值。
- 计算空闲内存块:
- 遍历所有可能的空闲区域,计算其大小。
- 记录每个空闲区域的起始地址和大小。
- 选择合适的内存块:
- 优先选择紧接着已使用内存块后的空闲区域。
- 如果空闲区域足够大,则选择最接近申请大小的内存块。
- 返回结果:
- 如果找到合适的内存块,返回其起始地址。
- 如果未找到合适的内存块,返回 -1。
六、Python算法源码
class MemoryBlock:
def __init__(self, start, size):
self.start = start
self.size = size
def calculate_free_blocks(allocated_blocks, total_size):
free_blocks = []
# 检查起始位置是否有空闲块
if not allocated_blocks or allocated_blocks[0].start > 0:
end = total_size if not allocated_blocks else allocated_blocks[0].start
free_blocks.append(MemoryBlock(0, end))
# 检查已分配块之间的空闲区域
for i in range(len(allocated_blocks) - 1):
end_current = allocated_blocks[i].start + allocated_blocks[i].size
start_next = allocated_blocks[i + 1].start
if start_next > end_current:
free_blocks.append(MemoryBlock(end_current, start_next - end_current))
# 检查最后一个已分配块后面的空闲区域
if allocated_blocks:
end_last = allocated_blocks[-1].start + allocated_blocks[-1].size
if end_last < total_size:
free_blocks.append(MemoryBlock(end_last, total_size - end_last))
return free_blocks
def find_suitable_block(free_blocks, request_size):
best_fit = None
for block in free_blocks:
if block.size >= request_size:
if best_fit is None or block.size < best_fit.size:
best_fit = block
return best_fit.start if best_fit else -1
def main():
# 读取输入
arr1 = list(map(int, input().split()))
request_size = arr1[0]
n = arr1[1]
# 用于存储已分配的内存块
allocated_blocks = []
for _ in range(n):
arr = list(map(int, input().split()))
start = arr[0]
size = arr[1]
allocated_blocks.append(MemoryBlock(start, size))
# 对已分配的内存块进行排序,按照偏移地址排序
allocated_blocks.sort(key=lambda block: block.start)
# 计算空闲内存块
free_blocks = calculate_free_blocks(allocated_blocks, 100)
# 找到最合适的空闲块
allocation_start = find_suitable_block(free_blocks, request_size)
# 输出结果
print(allocation_start)
if __name__ == "__main__":
main()
七、JavaScript算法源码
class MemoryBlock {
constructor(start, size) {
this.start = start;
this.size = size;
}
}
function calculateFreeBlocks(allocatedBlocks, totalSize) {
const freeBlocks = [];
// 检查起始位置是否有空闲块
if (allocatedBlocks.length === 0 || allocatedBlocks[0].start > 0) {
const end = allocatedBlocks.length === 0 ? totalSize : allocatedBlocks[0].start;
freeBlocks.push(new MemoryBlock(0, end));
}
// 检查已分配块之间的空闲区域
for (let i = 0; i < allocatedBlocks.length - 1; i++) {
const endCurrent = allocatedBlocks[i].start + allocatedBlocks[i].size;
const startNext = allocatedBlocks[i + 1].start;
if (startNext > endCurrent) {
freeBlocks.push(new MemoryBlock(endCurrent, startNext - endCurrent));
}
}
// 检查最后一个已分配块后面的空闲区域
if (allocatedBlocks.length > 0) {
const endLast = allocatedBlocks[allocatedBlocks.length - 1].start + allocatedBlocks[allocatedBlocks.length - 1].size;
if (endLast < totalSize) {
freeBlocks.push(new MemoryBlock(endLast, totalSize - endLast));
}
}
return freeBlocks;
}
function findSuitableBlock(freeBlocks, requestSize) {
let bestFit = null;
for (const block of freeBlocks) {
if (block.size >= requestSize) {
if (bestFit === null || block.size < bestFit.size) {
bestFit = block;
}
}
}
return bestFit ? bestFit.start : -1;
}
function main() {
// 读取输入
const input1 = prompt("请输入请求的内存大小和块数 (空格分隔):").split(" ");
const requestSize = parseInt(input1[0]);
const n = parseInt(input1[1]);
// 用于存储已分配的内存块
const allocatedBlocks = [];
for (let i = 0; i < n; i++) {
const input = prompt("请输入内存块的起始地址和大小 (空格分隔):").split(" ");
const start = parseInt(input[0]);
const size = parseInt(input[1]);
allocatedBlocks.push(new MemoryBlock(start, size));
}
// 对已分配的内存块进行排序,按照偏移地址排序
allocatedBlocks.sort((block1, block2) => block1.start - block2.start);
// 计算空闲内存块
const freeBlocks = calculateFreeBlocks(allocatedBlocks, 100);
// 找到最合适的空闲块
const allocationStart = findSuitableBlock(freeBlocks, requestSize);
// 输出结果
console.log(allocationStart);
}
// 调用主函数
main();
八、C算法源码
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int start;
int size;
} MemoryBlock;
int compare(const void* a, const void* b) {
MemoryBlock* blockA = (MemoryBlock*)a;
MemoryBlock* blockB = (MemoryBlock*)b;
return blockA->start - blockB->start;
}
MemoryBlock* calculateFreeBlocks(MemoryBlock* allocatedBlocks, int n, int totalSize, int* freeCount) {
MemoryBlock* freeBlocks = (MemoryBlock*)malloc((n + 1) * sizeof(MemoryBlock));
*freeCount = 0;
// 检查起始位置是否有空闲块
if (n == 0 || allocatedBlocks[0].start > 0) {
int end = (n == 0) ? totalSize : allocatedBlocks[0].start;
freeBlocks[*freeCount].start = 0;
freeBlocks[*freeCount].size = end;
(*freeCount)++;
}
// 检查已分配块之间的空闲区域
for (int i = 0; i < n - 1; i++) {
int endCurrent = allocatedBlocks[i].start + allocatedBlocks[i].size;
int startNext = allocatedBlocks[i + 1].start;
if (startNext > endCurrent) {
freeBlocks[*freeCount].start = endCurrent;
freeBlocks[*freeCount].size = startNext - endCurrent;
(*freeCount)++;
}
}
// 检查最后一个已分配块后面的空闲区域
if (n > 0) {
int endLast = allocatedBlocks[n - 1].start + allocatedBlocks[n - 1].size;
if (endLast < totalSize) {
freeBlocks[*freeCount].start = endLast;
freeBlocks[*freeCount].size = totalSize - endLast;
(*freeCount)++;
}
}
return freeBlocks;
}
int findSuitableBlock(MemoryBlock* freeBlocks, int freeCount, int requestSize) {
MemoryBlock* bestFit = NULL;
for (int i = 0; i < freeCount; i++) {
if (freeBlocks[i].size >= requestSize) {
if (bestFit == NULL || freeBlocks[i].size < bestFit->size) {
bestFit = &freeBlocks[i];
}
}
}
return (bestFit != NULL) ? bestFit->start : -1;
}
int main() {
int requestSize, n;
// 读取请求的内存大小和块数
printf("请输入请求的内存大小和块数: ");
scanf("%d %d", &requestSize, &n);
// 用于存储已分配的内存块
MemoryBlock* allocatedBlocks = (MemoryBlock*)malloc(n * sizeof(MemoryBlock));
for (int i = 0; i < n; i++) {
printf("请输入内存块的起始地址和大小: ");
scanf("%d %d", &allocatedBlocks[i].start, &allocatedBlocks[i].size);
}
// 对已分配的内存块进行排序,按照偏移地址排序
qsort(allocatedBlocks, n, sizeof(MemoryBlock), compare);
// 计算空闲内存块
int freeCount;
MemoryBlock* freeBlocks = calculateFreeBlocks(allocatedBlocks, n, 100, &freeCount);
// 找到最合适的空闲块
int allocationStart = findSuitableBlock(freeBlocks, freeCount, requestSize);
// 输出结果
printf("%d\n", allocationStart);
// 释放内存
free(allocatedBlocks);
free(freeBlocks);
return 0;
}
九、C++算法源码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct MemoryBlock {
int start;
int size;
MemoryBlock(int s, int sz) : start(s), size(sz) {}
};
bool compareMemoryBlocks(const MemoryBlock& a, const MemoryBlock& b) {
return a.start < b.start;
}
vector<MemoryBlock> calculateFreeBlocks(const vector<MemoryBlock>& allocatedBlocks, int totalSize) {
vector<MemoryBlock> freeBlocks;
// 检查起始位置是否有空闲块
if (allocatedBlocks.empty() || allocatedBlocks[0].start > 0) {
int end = allocatedBlocks.empty() ? totalSize : allocatedBlocks[0].start;
freeBlocks.emplace_back(0, end);
}
// 检查已分配块之间的空闲区域
for (size_t i = 0; i < allocatedBlocks.size() - 1; ++i) {
int endCurrent = allocatedBlocks[i].start + allocatedBlocks[i].size;
int startNext = allocatedBlocks[i + 1].start;
if (startNext > endCurrent) {
freeBlocks.emplace_back(endCurrent, startNext - endCurrent);
}
}
// 检查最后一个已分配块后面的空闲区域
if (!allocatedBlocks.empty()) {
int endLast = allocatedBlocks.back().start + allocatedBlocks.back().size;
if (endLast < totalSize) {
freeBlocks.emplace_back(endLast, totalSize - endLast);
}
}
return freeBlocks;
}
int findSuitableBlock(const vector<MemoryBlock>& freeBlocks, int requestSize) {
const MemoryBlock* bestFit = nullptr;
for (const auto& block : freeBlocks) {
if (block.size >= requestSize) {
if (bestFit == nullptr || block.size < bestFit->size) {
bestFit = █
}
}
}
return bestFit ? bestFit->start : -1;
}
int main() {
int requestSize, n;
// 读取请求的内存大小和块数
cout << "请输入请求的内存大小和块数: ";
cin >> requestSize >> n;
// 用于存储已分配的内存块
vector<MemoryBlock> allocatedBlocks;
for (int i = 0; i < n; ++i) {
int start, size;
cout << "请输入内存块的起始地址和大小: ";
cin >> start >> size;
allocatedBlocks.emplace_back(start, size);
}
// 对已分配的内存块进行排序,按照偏移地址排序
sort(allocatedBlocks.begin(), allocatedBlocks.end(), compareMemoryBlocks);
// 计算空闲内存块
vector<MemoryBlock> freeBlocks = calculateFreeBlocks(allocatedBlocks, 100);
// 找到最合适的空闲块
int allocationStart = findSuitableBlock(freeBlocks, requestSize);
// 输出结果
cout << allocationStart << endl;
return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。