华为OD机试 2024E卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
区块链底层存储是一个链式文件系统,由顺序的N个文件组成,每个文件的大小不一,依次为F1,F2…Fn。
随着时间的推移,所占存储会越来越大。
云平台考虑将区块链按文件转储到廉价的SATA盘,只有连续的区块链文件才能转储到SATA盘上,且转储的文件之和不能超过SATA盘的容量。
假设每块SATA盘容量为M,求能转储的最大连续文件大小之和。
二、输入描述
第一行为SATA盘容量M,1000<=M<=1000000
第二行为区块链文件大小序列F1,F2…Fn。其中 1<=n<=100000, 1<=Fi<=500
三、输出描述
求能转储的最大连续文件大小之和
四、测试用例
1、输入
1000
100 300 500 400 400 150 100
2、输出
950
3、说明
最大序列和为950,序列为[400,400,150]。
五、解题思路
- 使用双指针法遍历文件序列arr,通过移动指针来找到能转储的最大连续文件大小之和;
- 将当前文件大小加到curr上;
- 如果curr小于等于M,更新ret为curr和ret中的较大值,右指针r向右移动一位;
- 如果curr大于M,说明当前连续文件大小之和超过了SATA盘容量,需要调整边界来找到新的连续文件;
- 输出能转储的最大连续文件大小之和ret;
六、Python算法源码
# 导入必要的库
import sys
def main():
# 读取标准输入的所有行,并去除末尾的换行符
lines = sys.stdin.read().splitlines()
# 第1行:SATA盘容量M,转换为整数
M = int(lines[0])
# 第2行:区块链文件大小序列,转换为整数列表
arr = list(map(int, lines[1].split()))
# 序列arr的长度n
n = len(arr)
# 连续文件的左边界l,初始为0
l = 0
# 连续文件的右边界r,初始为0
r = 0
# 当前连续文件大小之和curr,初始为0
curr = 0
# 能转储的最大连续文件大小之和ret,初始为0
ret = 0
# 使用双指针法遍历文件序列arr,通过移动指针来找到能转储的最大连续文件大小之和
while r < n:
# 将当前文件大小加到curr上
curr += arr[r]
# 如果curr小于等于M,更新ret为curr和ret中的较大值,右指针r向右移动一位
if curr <= M:
ret = max(ret, curr)
r += 1
else:
# 如果curr大于M,说明当前连续文件大小之和超过了SATA盘容量,需要调整边界来找到新的连续文件
# 将左指针l指向的文件大小从curr中减去
curr -= arr[l]
# 左指针l向右移动一位
l += 1
# 输出能转储的最大连续文件大小之和ret
print(ret)
# 调用主函数
if __name__ == "__main__":
main()
七、JavaScript算法源码
// 定义资源分配函数
function main() {
const fs = require('fs');
// 读取所有输入内容,并按行分割
const input = fs.readFileSync('/dev/stdin', 'utf8').trim().split('\n');
// 第1行:SATA盘容量M,转换为整数
const M = parseInt(input[0]);
// 第2行:区块链文件大小序列,转换为整数数组
const arr = input[1].split(' ').map(Number);
// 序列arr的长度n
const n = arr.length;
// 连续文件的左边界l,初始为0
let l = 0;
// 连续文件的右边界r,初始为0
let r = 0;
// 当前连续文件大小之和curr,初始为0
let curr = 0;
// 能转储的最大连续文件大小之和ret,初始为0
let ret = 0;
// 使用双指针法遍历文件序列arr,通过移动指针来找到能转储的最大连续文件大小之和
while (r < n) {
// 将当前文件大小加到curr上
curr += arr[r];
// 如果curr小于等于M,更新ret为curr和ret中的较大值,右指针r向右移动一位
if (curr <= M) {
ret = Math.max(ret, curr);
r += 1;
} else {
// 如果curr大于M,说明当前连续文件大小之和超过了SATA盘容量,需要调整边界来找到新的连续文件
// 将左指针l指向的文件大小从curr中减去
curr -= arr[l];
// 左指针l向右移动一位
l += 1;
}
}
// 输出能转储的最大连续文件大小之和ret
console.log(ret);
}
// 调用主函数
main();
八、C算法源码
#include <stdio.h>
// 主函数
int main() {
int M; // 定义SATA盘容量M
// 读取SATA盘容量M
scanf("%d", &M);
// 定义文件大小数组,最大可能为100000个文件
int arr[100000];
int n = 0; // 文件数量初始化为0
// 读取区块链文件大小序列,直到换行或文件结束
while (scanf("%d", &arr[n]) != EOF) {
n++;
// 防止数组越界
if (n >= 100000) {
break;
}
}
int l = 0; // 连续文件的左边界l,初始为0
int r = 0; // 连续文件的右边界r,初始为0
long long curr = 0; // 当前连续文件大小之和curr,使用long long防止溢出
long long ret = 0; // 能转储的最大连续文件大小之和ret,使用long long
// 使用双指针法遍历文件序列arr,通过移动指针来找到能转储的最大连续文件大小之和
while (r < n) {
// 将当前文件大小加到curr上
curr += arr[r];
// 如果curr小于等于M,更新ret为curr和ret中的较大值,右指针r向右移动一位
if (curr <= M) {
if (curr > ret) {
ret = curr;
}
r++;
} else {
// 如果curr大于M,说明当前连续文件大小之和超过了SATA盘容量,需要调整边界来找到新的连续文件
// 将左指针l指向的文件大小从curr中减去
curr -= arr[l];
// 左指针l向右移动一位
l++;
}
}
// 输出能转储的最大连续文件大小之和ret
printf("%lld\n", ret);
return 0; // 程序结束
}
九、C++算法源码
#include <iostream>
#include <vector>
using namespace std;
// 主函数
int main(){
ios::sync_with_stdio(false); // 关闭同步,提高输入输出效率
cin.tie(0); // 取消cin和cout的绑定
long long M; // 定义SATA盘容量M,使用long long防止溢出
cin >> M; // 读取SATA盘容量M
vector<int> arr; // 定义文件大小数组
int num;
// 读取区块链文件大小序列,直到换行或文件结束
while(cin >> num){
arr.push_back(num);
}
int n = arr.size(); // 文件数量
int l = 0; // 连续文件的左边界l,初始为0
int r = 0; // 连续文件的右边界r,初始为0
long long curr = 0; // 当前连续文件大小之和curr
long long ret = 0; // 能转储的最大连续文件大小之和ret
// 使用双指针法遍历文件序列arr,通过移动指针来找到能转储的最大连续文件大小之和
while (r < n) {
// 将当前文件大小加到curr上
curr += arr[r];
// 如果curr小于等于M,更新ret为curr和ret中的较大值,右指针r向右移动一位
if (curr <= M) {
if (curr > ret) {
ret = curr;
}
r++;
} else {
// 如果curr大于M,说明当前连续文件大小之和超过了SATA盘容量,需要调整边界来找到新的连续文件
// 将左指针l指向的文件大小从curr中减去
curr -= arr[l];
// 左指针l向右移动一位
l++;
}
}
// 输出能转储的最大连续文件大小之和ret
cout << ret << "\n";
return 0; // 程序结束
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。