
华为OD机试 2024E卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
静态扫描可以快速识别源代码的缺陷,静态扫描的结果以扫描报告作为输出:
- 文件扫描的成本和文件大小相关,如果文件大小为N,则扫描成本为N个金币。
- 扫描报告的缓存成本和文件大小无关,每缓存一个报告需要M个金币。
- 扫描报告缓存后,后续再碰到该文件则不需要扫描成本,直接获取缓存结果。
给出源代码文件标识序列F和文件大小序列S,求解采用合理的缓存策略Q,最少需要的金币数。
二、输入描述
第一行为缓存一个报告金币数M,L <= M <= 100。
第二行为文件标识序列:F1,F2,F3,…,Fn。
第三行为文件大小序列:S1,S2,S3,…,Sn。
备注:
1 <= N <= 10000
 1 <= Fi <= 1000
 1 <= Si <= 10
三、输出描述
采用合理的缓存策略,需最少的金币数。
四、测试用例
测试用例1:
1、输入
5
 1 2 2 1 3 4
 1 1 1 1 1 1
2、输出
6
3、说明
文件1和文件2各出现2次,文件3和文件4各出现1次。
判断是否缓存:
文件1:M=5 vs (2-1)1=1 → 不缓存,成本 21=2
 文件2:M=5 vs (2-1)1=1 → 不缓存,成本 21=2
 文件3:出现1次,不缓存,成本 11=1
 文件4:出现1次,不缓存,成本 11=1
总成本:2 + 2 + 1 + 1 = 6
测试用例2:
1、输入
5
 2 2 2 2 2
 3 3 3 3 3
2、输出
8
3、说明
文件2出现5次,大小为3。
 判断是否缓存:
 文件2:M=5 vs (5-1)*3=12 → 缓存,成本 3 + 5=8
 总成本:8
五、解题思路
- 统计文件出现次数和大小 
  - 使用两个哈希表(或字典)
- fileFrequencyMap:记录每个文件ID出现的次数,fileSizeMap:记录每个文件ID对应的文件大小。
 
- 计算总成本 
  - 遍历每个唯一的文件ID,对于每个文件,比较两种策略的成本: 
    - 不缓存:每次扫描都需要支付文件大小的成本,总成本为 frequency * size。
- 缓存:第一次扫描支付文件大小的成本和缓存成本 M,后续不需要再次支付扫描成本,总成本为 size + M。
 
- 选择两种策略中成本较低的一种,累加到总成本中。
 
- 遍历每个唯一的文件ID,对于每个文件,比较两种策略的成本: 
    
- 输出结果: 
  - 输出计算得到的最小总金币成本。
 
对于每个文件,若 frequency * size 小于或等于 size + M,则不缓存,支付总扫描成本;否则,选择缓存,支付 size + M。
六、Python算法源码
# 导入所需模块
import sys
def calculate_total_cost(M, file_ids, file_sizes):
    """
    计算总扫描成本
    :param M: 缓存一个报告的金币数
    :param file_ids: 文件ID列表
    :param file_sizes: 文件大小列表
    :return: 最小总金币数
    """
    # 使用字典统计每个文件ID的出现次数
    file_frequency_map = {}
    # 使用字典记录每个文件ID对应的文件大小
    file_size_map = {}
    
    # 遍历所有文件,统计频率和记录大小
    for file_id, size in zip(file_ids, file_sizes):
        if file_id in file_frequency_map:
            file_frequency_map[file_id] += 1
        else:
            file_frequency_map[file_id] = 1
            file_size_map[file_id] = size
    
    total_cost = 0
    # 遍历每个唯一的文件ID,计算最小成本
    for file_id in file_frequency_map:
        frequency = file_frequency_map[file_id]
        size = file_size_map[file_id]
        # 不缓存的成本
        cost_without_cache = frequency * size
        # 缓存的成本
        cost_with_cache = size + M
        # 选择较小的成本
        total_cost += min(cost_without_cache, cost_with_cache)
    
    return total_cost
def main():
    # 读取标准输入的所有行
    lines = sys.stdin.read().splitlines()
    # 去除可能的空行
    lines = [line.strip() for line in lines if line.strip()]
    
    # 读取缓存成本M
    M = int(lines[0])
    
    # 读取文件ID列表
    file_ids = list(map(int, lines[1].split()))
    
    # 读取文件大小列表
    file_sizes = list(map(int, lines[2].split()))
    
    # 计算总成本
    total_cost = calculate_total_cost(M, file_ids, file_sizes)
    
    # 输出结果
    print(total_cost)
if __name__ == "__main__":
    main()
七、JavaScript算法源码
// 导入所需模块
const readline = require('readline');
// 创建接口以读取标准输入
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});
let inputLines = [];
rl.on('line', (line) => {
    inputLines.push(line.trim());
    // 当已经读取了三行输入时,开始处理
    if (inputLines.length === 3) {
        rl.close();
    }
});
rl.on('close', () => {
    // 读取缓存成本M
    const M = parseInt(inputLines[0]);
    // 读取文件ID列表
    const fileIds = inputLines[1].split(' ').map(Number);
    // 读取文件大小列表
    const fileSizes = inputLines[2].split(' ').map(Number);
    // 计算总成本
    const totalCost = calculateTotalCost(M, fileIds, fileSizes);
    // 输出结果
    console.log(totalCost);
});
/**
 * 计算总扫描成本
 * @param {number} M 缓存一个报告的金币数
 * @param {number[]} fileIds 文件ID数组
 * @param {number[]} fileSizes 文件大小数组
 * @returns {number} 最小总金币数
 */
function calculateTotalCost(M, fileIds, fileSizes) {
    // 使用对象统计每个文件ID的出现次数
    const fileFrequencyMap = {};
    // 使用对象记录每个文件ID对应的文件大小
    const fileSizeMap = {};
    // 遍历所有文件,统计频率和记录大小
    for (let i = 0; i < fileIds.length; i++) {
        const fileId = fileIds[i];
        const size = fileSizes[i];
        if (fileFrequencyMap.hasOwnProperty(fileId)) {
            fileFrequencyMap[fileId] += 1;
        } else {
            fileFrequencyMap[fileId] = 1;
            fileSizeMap[fileId] = size;
        }
    }
    let totalCost = 0;
    // 遍历每个唯一的文件ID,计算最小成本
    for (const fileId in fileFrequencyMap) {
        const frequency = fileFrequencyMap[fileId];
        const size = fileSizeMap[fileId];
        const costWithoutCache = frequency * size;
        const costWithCache = size + M;
        totalCost += Math.min(costWithoutCache, costWithCache);
    }
    return totalCost;
}
八、C算法源码
#include <stdio.h>
#include <stdlib.h>
// 定义最大文件ID范围
#define MAX_FILE_ID 1001
int main() {
    int M;
    // 读取缓存成本M
    scanf("%d", &M);
    
    // 定义数组存储文件ID和文件大小
    int fileIds[10000];
    int fileSizes[10000];
    
    int count = 0;
    // 读取文件ID,直到换行或文件大小输入开始
    while (scanf("%d", &fileIds[count]) != EOF) {
        count++;
        // 假设文件大小与文件ID数量相同
        if (count >= 10000) break;
    }
    
    // 重新定位输入流到读取文件大小
    // 假设输入格式正确,文件大小紧跟文件ID之后
    // 重新读取文件大小
    for (int i = 0; i < count; i++) {
        scanf("%d", &fileSizes[i]);
    }
    
    // 使用数组统计文件频率,文件大小
    int fileFrequencyMap[MAX_FILE_ID] = {0};
    int fileSizeMap[MAX_FILE_ID] = {0};
    
    for (int i = 0; i < count; i++) {
        int fileId = fileIds[i];
        int size = fileSizes[i];
        fileFrequencyMap[fileId]++;
        if (fileFrequencyMap[fileId] == 1) {
            fileSizeMap[fileId] = size;
        }
    }
    
    long long totalCost = 0;
    // 遍历所有可能的文件ID,计算成本
    for (int fileId = 0; fileId < MAX_FILE_ID; fileId++) {
        if (fileFrequencyMap[fileId] > 0) {
            int frequency = fileFrequencyMap[fileId];
            int size = fileSizeMap[fileId];
            long long costWithoutCache = (long long)frequency * size;
            long long costWithCache = (long long)size + M;
            // 选择较小的成本
            if (costWithoutCache <= costWithCache) {
                totalCost += costWithoutCache;
            } else {
                totalCost += costWithCache;
            }
        }
    }
    
    // 输出结果
    printf("%lld\n", totalCost);
    
    return 0;
}
九、C++算法源码
#include <bits/stdc++.h>
using namespace std;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    int M;
    // 读取缓存成本M
    cin >> M;
    
    // 读取文件ID序列
    vector<int> fileIds;
    string line;
    // 读取文件ID
    while(cin.peek() != '\n' && !cin.eof()){
        int id;
        cin >> id;
        fileIds.push_back(id);
    }
    // 读取换行符
    getline(cin, line);
    
    // 读取文件大小序列
    vector<int> fileSizes;
    while(cin >> ws && !cin.eof()){
        int size;
        cin >> size;
        fileSizes.push_back(size);
    }
    
    // 使用unordered_map统计频率和记录大小
    unordered_map<int, int> fileFrequencyMap;
    unordered_map<int, int> fileSizeMap;
    
    for(int i=0; i<fileIds.size(); i++){
        int fileId = fileIds[i];
        int size = fileSizes[i];
        fileFrequencyMap[fileId]++;
        if(fileFrequencyMap[fileId] == 1){
            fileSizeMap[fileId] = size;
        }
    }
    
    long long totalCost = 0;
    // 遍历每个文件,计算最小成本
    for(auto &entry: fileFrequencyMap){
        int fileId = entry.first;
        int frequency = entry.second;
        int size = fileSizeMap[fileId];
        long long costWithoutCache = (long long)frequency * size;
        long long costWithCache = (long long)size + M;
        totalCost += min(costWithoutCache, costWithCache);
    }
    
    // 输出结果
    cout << totalCost << "\n";
    
    return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。




![[240929] 12 款最佳免费开源隐写工具 | Llama 3.2: 开源、可定制模型,革新边缘人工智能和视觉体验](https://i-blog.csdnimg.cn/direct/cb736925c2a2433f98c6d9928399479f.png#pic_center)










![World of Warcraft [CLASSIC][80][Alonsus][Dark Iron Legacy]](https://i-blog.csdnimg.cn/direct/e20589854293425ea970af138be00670.jpeg)




