2025 A卷 100分 题型
本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式;
并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析;
本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分享》
华为OD机试真题《告警抑制》:
文章快捷目录
题目描述及说明
Java
python
JavaScript
C
GO
题目名称:告警抑制
- 知识点:字符串处理、哈希映射(逻辑处理)
- 时间限制:1秒
- 空间限制:256MB
- 限定语言:不限
题目描述
告警抑制是指高优先级告警抑制低优先级告警的规则。高优先级告警产生后,低优先级告警不再产生。请根据原始告警列表和告警抑制关系,给出实际产生的告警列表。
输入描述:
- 第一行为数字
N
,表示告警抑制关系个数(0 ≤ N ≤ 120)。 - 接下来
N
行,每行由空格分隔的两个告警ID(格式:大写字母+0或1个数字),例如A B
,表示A
抑制B
。 - 最后一行为告警产生列表,列表长度范围为 [1,100],告警ID间以空格分隔。
输出描述:
真实产生的告警列表(未被抑制的告警),按输入顺序输出,ID间以空格分隔。
示例:
输入:
2
A B
B C
A B C D E
输出:
A D E
解释:
A
抑制B
,B
抑制C
,因此B
和C
被抑制,最终输出A D E
。
补充规则:
- 无循环抑制:不会出现
A→B→A
的循环关系。 - 无传递抑制:例如
A→B→C
时,A
不直接抑制C
,但被抑制的B
仍可抑制C
。 - 位置无关:被抑制的告警无论在高优先级告警的前后,均被屏蔽。
Java
问题分析
我们需要根据给定的告警抑制关系和原始告警列表,输出实际产生的未被抑制的告警列表。高优先级告警会抑制低优先级告警,无论它们在输入列表中的顺序如何。
解题思路
- 建立抑制关系映射:记录每个告警被哪些高优先级告警抑制。
- 快速判断抑制存在性:通过集合快速检查某个告警是否存在于输入列表中。
- 遍历原始告警列表:对于每个告警,检查是否存在抑制它的告警存在于输入列表中,若存在则过滤,否则保留。
代码实现
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = Integer.parseInt(scanner.nextLine()); // 读取抑制关系个数
// 建立抑制关系映射表:key是被抑制的告警,value是抑制它的告警集合
Map<String, Set<String>> suppressionMap = new HashMap<>();
for (int i = 0; i < N; i++) {
String[] parts = scanner.nextLine().split(" ");
String suppressor = parts[0]; // 抑制者,例如A
String suppressed = parts[1]; // 被抑制者,例如B
if (!suppressionMap.containsKey(suppressed)) {
suppressionMap.put(suppressed, new HashSet<>());
}
suppressionMap.get(suppressed).add(suppressor);
}
// 读取原始告警列表,并转换为集合用于快速查询
String[] alerts = scanner.nextLine().split(" ");
Set<String> inputSet = new HashSet<>(Arrays.asList(alerts));
List<String> result = new ArrayList<>(); // 保存未被抑制的告警
for (String alert : alerts) {
boolean isSuppressed = false;
// 检查当前告警是否有抑制者存在于输入列表中
if (suppressionMap.containsKey(alert)) {
for (String suppressor : suppressionMap.get(alert)) {
if (inputSet.contains(suppressor)) {
isSuppressed = true;
break;
}
}
}
if (!isSuppressed) {
result.add(alert); // 未被抑制,加入结果
}
}
// 按输入顺序输出结果
System.out.println(String.join(" ", result));
}
}
代码详细解析
- 读取抑制关系个数:使用
scanner.nextLine()
读取第一行并转换为整数N
。 - 建立抑制关系映射:
- 使用
HashMap
存储,键为被抑制的告警,值为抑制它的告警集合。 - 遍历
N
行,每行拆分为抑制者和被抑制者,将被抑制者作为键,抑制者添加到对应的集合。
- 使用
- 读取原始告警列表:拆分为数组并转换为集合
inputSet
用于快速查询。 - 过滤被抑制的告警:
- 遍历每个告警,检查是否存在抑制它的告警在
inputSet
中。 - 若存在,则跳过;否则加入结果列表。
- 遍历每个告警,检查是否存在抑制它的告警在
- 输出结果:按输入顺序拼接未被抑制的告警。
示例测试
示例1:
输入:
2
A B
B C
A B C D E
输出:
A D E
解析:A 抑制 B,B 抑制 C,B 和 C 被过滤,D、E 无抑制。
示例2:
输入:
1
B A
B A
输出:
B
解析:B 抑制 A,A 被过滤,B 被保留。
示例3:
输入:
0
A B C
输出:
A B C
解析:无抑制关系,所有告警均保留。
综合分析
- 时间复杂度:O(N + M*K),其中 N 为抑制关系数,M 为告警列表长度,K 为每个告警的抑制者数量。高效处理最大数据规模。
- 空间复杂度:O(N + M),存储抑制关系和输入集合。
- 正确性:通过抑制关系映射和集合查询,确保所有抑制条件被正确判断。
- 适用性:处理所有合法输入,包括重复告警和不同顺序的抑制关系。
python
问题分析
我们需要根据给定的告警抑制关系和原始告警列表,输出实际产生的未被抑制的告警列表。高优先级告警会抑制低优先级告警,无论它们在输入列表中的顺序如何。
解题思路
- 建立抑制关系映射:记录每个告警被哪些高优先级告警抑制。
- 快速判断抑制存在性:通过集合快速检查某个告警是否存在于输入列表中。
- 遍历原始告警列表:对于每个告警,检查是否存在抑制它的告警存在于输入列表中,若存在则过滤,否则保留。
代码实现
from collections import defaultdict
def main():
n = int(input()) # 读取抑制关系个数
suppression = defaultdict(set) # 抑制关系映射表:被抑制的告警 → 抑制它的告警集合
# 读取所有抑制关系
for _ in range(n):
suppressor, suppressed =