华为OD机试真题——报文回路(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
2025 A卷 100分 题型
本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式;
并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析;
本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分享》
华为OD机试真题《报文回路》:
文章快捷目录
题目描述及说明
Java
python
JavaScript
C
GO
题目名称:报文回路
- 知识点:图论(邻接表遍历)、逻辑处理
- 时间限制:1秒
- 空间限制:256MB
- 限定语言:不限
题目描述
IGMP协议中,响应报文和查询报文是维系组播通路的两个重要报文。在已建立的组播通路中,相邻的HOST和ROUTER之间,ROUTER会向HOST发送查询报文,HOST收到后需回复响应报文以维持连接。若双向报文缺失,则通路异常。现给定抓取的报文列表,判断组播通路是否正常。
输入描述
- 第一行:报文数量C(C ≤ 100)。
- 后续C行:每行两个设备节点D1和D2,表示D1到D2的单向报文(空格分隔)。
输出描述
- 通路正常输出
True
,否则输出False
。
示例
输入:
5
1 2
2 3
3 2
1 2
2 1
输出:
True
Java
问题分析
我们需要判断组播通路是否正常。组播通路的正常条件是:所有相邻设备的双向报文必须存在。即,对于每一条存在的 D1→D2 的报文,必须存在对应的 D2→D1 的报文。
解题思路
- 输入解析:读取所有报文,存储为边列表,并构建邻接表。
- 邻接表构建:用
Map
记录每个节点到其相邻节点的集合。 - 双向检查:遍历所有边,检查其反向边是否存在。
- 结果判定:若所有边的反向边均存在,返回
True
,否则False
。
代码实现
import java.util.*;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int C = scanner.nextInt(); // 读取报文数量List<int[]> edges = new ArrayList<>(); // 存储所有报文边Map<Integer, Set<Integer>> adjacencyMap = new HashMap<>(); // 邻接表// 读取所有报文并构建邻接表for (int i = 0; i < C; i++) {int D1 = scanner.nextInt();int D2 = scanner.nextInt();edges.add(new int[]{D1, D2}); // 存储边adjacencyMap.computeIfAbsent(D1, k -> new HashSet<>()).add(D2); // 记录D1→D2}// 遍历所有边,检查反向边是否存在boolean isValid = true;for (int[] edge : edges) {int D1 = edge[0];int D2 = edge[1];// 检查D2→D1是否存在if (!adjacencyMap.containsKey(D2) || !adjacencyMap.get(D2).contains(D1)) {isValid = false;break;}}System.out.println(isValid ? "True" : "False");}
}
代码详解
-
输入处理:
C
表示报文数量,后续读取C
条边。edges
列表存储所有输入的边(例如[D1, D2]
)。adjacencyMap
是邻接表,键为起始节点,值为所有可达节点的集合。
-
邻接表构建:
adjacencyMap.computeIfAbsent(D1, k -> new HashSet<>()).add(D2);
:若D1
不存在于邻接表,创建空集合,然后将D2
添加到集合中。
-
双向检查:
- 遍历所有边
edge
,检查反向边D2→D1
是否存在。 adjacencyMap.containsKey(D2)
:检查D2
是否有出边。adjacencyMap.get(D2).contains(D1)
:检查D2
的出边是否包含D1
。
- 遍历所有边
-
结果输出:
- 若所有边的反向边均存在,输出
True
,否则输出False
。
- 若所有边的反向边均存在,输出
示例测试
示例1:
输入:
5
1 2
2 3
3 2
1 2
2 1
输出&#x