华为OD机试真题 - 堆内存申请(Python/JS/C/C++ 2024 D卷 100分)

在这里插入图片描述

华为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. 若输入信息不合法或无效,则申请失败
  2. 若没有足够的空间供分配,则申请失败
  3. 堆内存信息有区域重叠或有非法值等都是无效输入

四、测试用例

1、输入

1 2
0 1
3 2

2、输出

1

3、说明

堆中已使用的两块内存是偏移从0开始的1字节和偏移从3开始的2字节,空闲的两块内存是偏移从1开始2个字节和偏移从5开始95字节根据分配原则,新申请的内存应从1开始分配1个字节,所以输出偏移为1。

五、解题思路

  1. 输入解析:
    • 第一行输入是期望申请的内存字节数。
    • 后续输入是已分配的内存块,用偏移地址和大小表示。
  2. 检查输入合法性:
    • 确保输入的内存块不重叠且偏移和大小均为有效值。
  3. 计算空闲内存块:
    • 遍历所有可能的空闲区域,计算其大小。
    • 记录每个空闲区域的起始地址和大小。
  4. 选择合适的内存块:
    • 优先选择紧接着已使用内存块后的空闲区域。
    • 如果空闲区域足够大,则选择最接近申请大小的内存块。
  5. 返回结果:
    • 如果找到合适的内存块,返回其起始地址。
    • 如果未找到合适的内存块,返回 -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 = &block;
            }
        }
    }

    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在线答疑。

在这里插入图片描述

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
首先,在选择服务中心的最佳位置时,我们需要考虑各种因素,包括人口密度、交通便利性、基础设施和竞争对手等。对于华为OD项目来说,我会推荐选址在人口密度相对较高的城市中心地带。这样可以确保服务中心能够覆盖到更多的用户群体,提高服务的便利性和覆盖面。 其次,交通便利性也是选择最佳位置的重要考量因素。一个位于交通枢纽地带的服务中心可以更容易地接触到周围城市的用户,减少用户的前往成本和时间。同时,也方便快速调度和配送产品,提高服务的效率和时效性。 此外,基础设施的完善也是一个重要的考虑因素。一个服务中心应该有稳定的电力、通讯和网络设施,以保证服务的持续性和稳定性。另外,周边商业设施和生活设施的配套也能吸引更多的顾客和员工,提高服务中心的吸引力和竞争力。 最后,对竞争对手的考虑也至关重要。在选择服务中心的位置时,需要做好竞争对手的地域析,避免选择在竞争对手的聚集地带,同时也要考虑如何在竞争对手密集的区域提供更优质的服务和更吸引人的特色,以获得竞争优势。 综上所述,选择服务中心最佳位置需要全面考虑各种因素,包括人口密度、交通便利性、基础设施和竞争对手,这样才能确保服务中心能够更好地为用户提供服务,同时也能提高企业的竞争力和影响力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值