华为OD机试 2024E卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
日志采集是运维系统的核心组件。日志是按行生成,每行记录做一条,由采集系统分批上报。
- 如果上报太频繁,会对服务端造成压力;
- 如果上报太晚,会降低用户的体验;
- 如果一次上报的条数太多,会导致接口失败。
为此,项目组设计了如下的上报策略:
- 每成功上报一条日志,奖励1分;
- 每条日志延迟上报1秒,扣1分;
- 积累日志达到100条,必须立刻上报。
给出日志序列,根据该规则,计算首次上报能获得的最多积分数。
二、输入描述
按时序产生的日志条数 T1,T2,…Tn,其中 1 <= n <= 1000,0 <= Ti <= 100
三、输出描述
首次上报最多能获得的积分分数
四、测试用例
测试用例1:
1、输入
1 98 1
2、输出
98
3、说明
T1时刻上报得1分
T2时刻上报得98分
最大 T3时刻上报得0分
测试用例2:
1、输入
50 60 1
2、输出
50
3、说明
如果第1个时刻上报,获得积分50。如果第2个时刻上报,最多上报100条,前50条延迟上报1s,每条扣除1分,共获得积分为100-50=50
五、解题思路
1、问题分析
为了计算首次上报的最大积分数,我们需要考虑以下几种情况:
- 在积累的日志数未达到100条时,可以选择任何时刻进行上报。此时,选择一个最佳的上报时刻,使得积分最大化。
- 当积累的日志数达到或超过100条时,必须在该时刻进行上报。此时,需要计算在这个时刻上报前100条日志的积分。
2、具体步骤
- 记录每个时间点到达的日志数:使用一个列表记录每个时间点到达的日志数量及其到达时间。
- 遍历每个时间点:
- 累积当前的日志数。
- 如果累积的日志数达到或超过100条:
- 必须在此时上报前100条日志。
- 计算前100条日志的积分。
- 更新最大积分数。
- 结束遍历,因为首次上报已经完成。
- 如果未达到100条,可以选择在此时上报:
- 计算当前时刻上报所有已累积的日志的积分。
- 更新最大积分数。
- 遍历结束后:
- 如果日志总数未达到100条,可以选择在最后一个时刻上报所有日志,确保积分最大化。
六、Python算法源码
import sys
from collections import deque
def main():
# 读取输入
input_line = sys.stdin.read()
tokens = input_line.strip().split()
n = len(tokens)
Ti_list = list(map(int, tokens))
# 初始化队列,用于存储日志的到达时间和数量
log_queue = deque()
# 累积的日志数量
accumulated_logs = 0
# 累积的 ti 总和
sum_ti_total = 0
# 最大积分
max_score = -float('inf')
for t in range(1, n+1):
Ti = Ti_list[t-1]
if Ti > 0:
log_queue.append((t, Ti)) # 添加到队列
accumulated_logs += Ti
sum_ti_total += Ti * t # 更新总的 ti
if accumulated_logs >= 100:
# 需要强制上传前100条日志
logs_needed = 100
sum_ti_first100 = 0
temp_queue = deque()
for log in log_queue:
ti, count = log
if logs_needed >= count:
sum_ti_first100 += ti * count
logs_needed -= count
else:
sum_ti_first100 += ti * logs_needed
temp_queue.append((ti, count - logs_needed))
logs_needed = 0
break
# 计算积分
score = sum_ti_first100 - 100 * (t -1)
if score > max_score:
max_score = score
break # 首次上传完成
else:
# 可以选择在此时上传所有累积的日志
score = sum_ti_total - accumulated_logs * (t -1)
if score > max_score:
max_score = score
# 如果所有时间点遍历完毕,且未达到100条日志
if accumulated_logs < 100 and n >0:
print(max_score)
elif n ==0:
print(0)
else:
print(max_score)
if __name__ == "__main__":
main()
七、JavaScript算法源码
const readline = require('readline');
function OdTest() {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let input = '';
rl.on('line', function(line) {
input += line;
});
rl.on('close', function() {
// 解析输入
const tokens = input.trim().split(/\s+/).map(Number);
const n = tokens.length;
const Ti_list = tokens;
// 初始化队列,用于存储日志的到达时间和数量
const log_queue = [];
// 累积的日志数量
let accumulated_logs = 0;
// 累积的 ti 总和
let sum_ti_total = 0;
// 最大积分
let max_score = -Infinity;
for (let t =1; t<=n; t++) {
const Ti = Ti_list[t-1];
if (Ti >0){
log_queue.push({ti: t, count: Ti});
}
accumulated_logs += Ti;
sum_ti_total += Ti * t;
if (accumulated_logs >=100){
// 需要强制上传前100条日志
let logs_needed = 100;
let sum_ti_first100 =0;
const temp_queue = [];
while (log_queue.length >0 && logs_needed >0){
const log = log_queue.shift();
if (log.count <= logs_needed){
sum_ti_first100 += log.ti * log.count;
logs_needed -= log.count;
} else {
sum_ti_first100 += log.ti * logs_needed;
log.count -= logs_needed;
temp_queue.push(log);
logs_needed =0;
}
}
// 将剩余的日志放回队列
while (temp_queue.length >0){
log_queue.unshift(temp_queue.pop());
}
// 计算积分
const score = sum_ti_first100 - 100 * (t -1);
if (score > max_score){
max_score = score;
}
break; // 首次上传完成
} else{
// 可以选择在此时上传所有累积的日志
const score = sum_ti_total - accumulated_logs * (t -1);
if (score > max_score){
max_score = score;
}
}
}
// 如果所有时间点遍历完毕,且未达到100条日志
if (accumulated_logs <100 && n >0){
console.log(max_score);
}
else if (n ==0){
console.log(0);
}
else{
console.log(max_score);
}
});
}
OdTest();
八、C算法源码
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int ti;
int count;
} LogEntry;
int main(){
// 读取输入
int Ti_list[1000];
int n =0;
while (scanf("%d", &Ti_list[n]) != EOF){
n++;
if(n >=1000){
break;
}
}
// 初始化队列
LogEntry queue[1000];
int front =0, rear=0;
// 累积的日志数量
int accumulated_logs =0;
// 累积的 ti 总和
long long sum_ti_total =0;
// 最大积分
long long max_score = -1000000000;
for(int t=1; t<=n; t++){
int Ti = Ti_list[t-1];
if(Ti >0){
queue[rear].ti = t;
queue[rear].count = Ti;
rear++;
}
accumulated_logs += Ti;
sum_ti_total += (long long)Ti * t;
if(accumulated_logs >=100){
// 需要强制上传前100条日志
int logs_needed =100;
long long sum_ti_first100 =0;
while(logs_needed >0 && front < rear){
if(queue[front].count <= logs_needed){
sum_ti_first100 += (long long)queue[front].ti * queue[front].count;
logs_needed -= queue[front].count;
front++;
}
else{
sum_ti_first100 += (long long)queue[front].ti * logs_needed;
queue[front].count -= logs_needed;
logs_needed =0;
}
}
// 计算积分
long long score = sum_ti_first100 - 100 * (t -1);
if(score > max_score){
max_score = score;
}
break; // 首次上传完成
}
else{
// 可以选择在此时上传所有累积的日志
long long score = sum_ti_total - (long long)accumulated_logs * (t -1);
if(score > max_score){
max_score = score;
}
}
}
// 如果所有时间点遍历完毕,且未达到100条日志
if(accumulated_logs <100 && n >0){
printf("%lld\n", max_score);
}
else if(n ==0){
printf("0\n");
}
else{
printf("%lld\n", max_score);
}
return 0;
}
九、C++算法源码
#include <bits/stdc++.h>
using namespace std;
struct LogEntry {
int ti;
int count;
};
int main(){
// 读取输入
vector<int> Ti_list;
int Ti;
while(cin >> Ti){
Ti_list.push_back(Ti);
}
int n = Ti_list.size();
// 初始化队列
deque<LogEntry> log_queue;
// 累积的日志数量
int accumulated_logs =0;
// 累积的 ti 总和
long long sum_ti_total =0;
// 最大积分
long long max_score = LLONG_MIN;
for(int t=1; t<=n; t++){
int current_Ti = Ti_list[t-1];
if(current_Ti >0){
log_queue.push_back(LogEntry{t, current_Ti});
}
accumulated_logs += current_Ti;
sum_ti_total += (long long)current_Ti * t;
if(accumulated_logs >=100){
// 需要强制上传前100条日志
int logs_needed =100;
long long sum_ti_first100 =0;
while(logs_needed >0 && !log_queue.empty()){
if(log_queue.front().count <= logs_needed){
sum_ti_first100 += (long long)log_queue.front().ti * log_queue.front().count;
logs_needed -= log_queue.front().count;
log_queue.pop_front();
}
else{
sum_ti_first100 += (long long)log_queue.front().ti * logs_needed;
log_queue.front().count -= logs_needed;
logs_needed =0;
}
}
// 计算积分
long long score = sum_ti_first100 - 100LL * (t -1);
if(score > max_score){
max_score = score;
}
break; // 首次上传完成
}
else{
// 可以选择在此时上传所有累积的日志
long long score = sum_ti_total - (long long)accumulated_logs * (t -1);
if(score > max_score){
max_score = score;
}
}
}
// 如果所有时间点遍历完毕,且未达到100条日志
if(accumulated_logs <100 && n >0){
cout << max_score << endl;
}
else if(n ==0){
cout << "0" << endl;
}
else{
cout << max_score << endl;
}
return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。