【华为OD-E卷-日志采集系统 100分(python、java、c++、js、c)】
题目
日志采集是运维系统的的核心组件。日志是按行生成,每行记做一条,由采集系统分批上报。
如果上报太频繁,会对服务端造成压力; 如果上报太晚,会降低用户的体验; 如果一次上报的条数太多,会导致超时失败。 为此,项目组设计了如下的上报策略:
每成功上报一条日志,奖励1分 每条日志每延迟上报1秒,扣1分 积累日志达到100条,必须立即上报 给出日志序列,根据该规则,计算首次上报能获得的最多积分数
输入描述
- 按时序产生的日志条数 T1,T2…Tn,其中
1 <= n <= 1000 0 <= Ti <= 100
输出描述
- 首次上报最多能获得的积分数
用例
用例一:
输入:
1 98 1
- 1
输出:
98
- 1
用例二:
输入:
50 60 1
- 1
输出:
50
- 1
用例三:
输入:
3 7 40 10 60
- 1
输出:
37
- 1
python解法
- 解题思路:
- 这段代码的目标是处理一个整数数组,并通过某种规则计算一个分数(score)。具体过程如下:
动态规划数组 dp
dp[i] 表示第 i 个位置的累计和,但是有一个上限,不能超过 100。
如果累计和达到 100,就停止进一步累加。
延迟数组 delay
delay[i] 通过调用 calculate_delay 函数计算得到,表示当前位置的累积延迟。
分数数组 score
score[i] 是当前位置的分数,通过调用 calculate_score 函数计算。
计算公式是 dp[i] - delay[i]。
逻辑流程
从数组的第一个元素开始,逐步计算 dp、delay 和 score。
如果 dp 达到上限 100,则停止计算。
最终返回 score 数组中的最大值。
def calculate_delay(dp, delay, i):
# 计算当前位置的累计延迟值
return delay[i - 1] + dp[i - 1]
def calculate_score(dp, delay, i):
# 计算当前位置的分数,dp值减去delay值
return dp[i] - delay[i]
def process_array(arr):
n = len(arr) # 数组的长度
dp = [0] * n # 用于存储累计和,且存在上限
delay = [0] * n # 存储累计延迟
score = [0] * n # 存储分数
dp[0] = arr[0] # 初始化第一个元素的累计和
score[0] = arr[0] # 第一个位置的分数
for i in range(1, n):
# 更新dp数组,累计和但不超过100
dp[i] = min(100, dp[i - 1] + arr[i])
# 计算当前的delay值
delay[i] = calculate_delay(dp, delay, i)
# 计算当前的分数
score[i] = calculate_score(dp, delay, i)
# 如果累计和达到100,提前结束循环
if dp[i] >= 100:
break
# 返回分数数组中的最大值
return max(score)
def getResult(arr):
# 处理数组并输出结果
result = process_array(arr)
print(result)
# 输入数组
arr = list(map(int, input().split()))
getResult(arr)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
java解法
- 解题思路
- 这段代码的目标是计算一个整数数组(logs)的最大得分,其中得分的计算受正向累积和以及**负分(惩罚)**的影响。具体思路如下:
正向累积和 (dp 数组)
表示从第一个元素开始累加到当前位置的和,但有一个限制:不能超过 100。
如果累积和达到 100,停止继续累加。
负分 (penalty 数组)
表示当前位置的累计惩罚值,它等于前一个位置的惩罚值加上前一个位置的累积和。
最终得分 (result 数组)
通过 dp[i] - penalty[i] 计算当前位置的得分,即正向累积和减去惩罚值。
逻辑流程
初始化数组的第一个位置的 dp 和 result。
遍历数组逐个更新 dp、penalty 和 result,同时检查 dp 是否达到 100,若达到则停止计算。
最终从 result 数组中取出最大值作为结果返回。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 读取输入并将其转化为整型数组
int[] logs = toIntArray(sc.nextLine());
// 输出最大得分
System.out.println(maxPoints(logs));
}
// 将输入字符串转化为整型数组
public static int[] toIntArray(String input) {
String[] parts = input.split(" "); // 按空格分割字符串
int[] result = new int[parts.length];
for (int i = 0; i < parts.length; i++) {
result[i] = Integer.parseInt(parts[i]); // 将每个字符串转为整数
}
return result;
}
// 动态规划计算最大得分
public static int maxPoints(int[] logs) {
int n = logs.length; // 数组长度
int[] dp = new int[n]; // 正向得分数组
int[] penalty = new int[n]; // 累积惩罚数组
int[] result = new int[n]; // 最终得分数组
dp[0] = logs[0]; // 初始化正向得分的第一个元素
penalty[0] = 0; // 第一个位置的惩罚值为0
result[0] = logs[0]; // 第一个位置的最终得分等于正向得分
for (int i = 1; i < n; i++) {
// 计算正向得分,累加和不能超过100
dp[i] = Math.min(100, dp[i - 1] + logs[i]);
// 计算当前的累积惩罚值
penalty[i] = penalty[i - 1] + dp[i - 1];
// 计算当前位置的最终得分
result[i] = dp[i] - penalty[i];
// 如果正向得分达到100,停止继续累加
if (dp[i] >= 100) {
break;
}
}
// 遍历result数组,找出最大得分
int maxScore = result[0];
for (int i = 1; i < n; i++) {
maxScore = Math.max(maxScore, result[i]);
}
return maxScore; // 返回最大得分
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
C++解法
- 解题思路
更新中
- 1
C解法
更新中
- 1
JS解法
更新中
- 1
注意:
如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏
评论记录:
回复评论: