华为OD机试_2025 B卷_精准核酸检测(Python,100分)(附详细解题思路)

题目描述

为了达到新冠疫情精准防控的需要,为了避免全员核酸检测带来的浪费,需要精准圈定可能被感染的人群。

现在根据传染病流调以及大数据分析,得到了每个人之间在时间、空间上是否存在轨迹交叉。

现在给定一组确诊人员编号(X1,X2,X3,…,Xn),在所有人当中,找出哪些人需要进行核酸检测,输出需要进行核酸检测的人数。(注意:确诊病例自身不需要再做核酸检测)

需要进行核酸检测的人,是病毒传播链条上的所有人员,即有可能通过确诊病例所能传播到的所有人。

例如:A是确诊病例,A和B有接触、B和C有接触、C和D有接触、D和E有接触,那么B\C\D\E都是需要进行核酸检测的人。

输入描述
第一行为总人数 N

第二行为确认病例人员编号(确诊病例人员数量 < N),用逗号分割

第三行开始,为一个 N * N 的矩阵,表示每个人员之间是否有接触,0表示没有接触,1表示有接触。

输出描述
整数:需要做核酸检测的人数

备注
人员编号从0开始
0 < N < 100

用例

输入 5
1,2
1,1,0,1,0
1,1,0,0,0
0,0,1,0,1
1,0,0,1,0
0,0,1,0,1
输出 3
说明

编号为1、2号的人员,为确诊病例。

1号和0号有接触,0号和3号有接触。

2号和4号有接触。

所以,需要做核酸检测的人是0号、3号、4号,总计3人需要进行核酸检测。

精准防控:如何高效圈定核酸检测人群?

在疫情防控中,如何精准找出需要检测的人群?这道题考察了图论的实际应用,通过分析人员接触关系,高效圈定传播链条上的风险人员。作为初学者,我将用最简单易懂的方式解析解题思路。

核心解题思路

题目本质是图的连通性问题:我们有一个由人员组成的网络(图),每个人是图中的节点,人员之间的接触关系是边。确诊人员是起始点,我们需要找到所有通过直接或间接接触与确诊人员相连的非确诊人员

这就像在一个社交网络中,我们要找出所有与确诊患者有过直接或间接接触的人。解决这类问题最有效的方法是广度优先搜索(BFS),它能从起始点逐层向外扩展,标记所有可达的节点。

关键步骤分解

  1. 标记起始点:所有确诊病例作为搜索起点
  2. 层级扩展:从起点出发,检查每个人的接触关系
  3. 标记访问:避免重复计数
  4. 排除确诊:最后结果不包含初始确诊者

完整解题过程

数据结构准备

# 读取总人数
n = int(input().strip())

# 读取确诊病例列表(字符串分割转整数)
confirmed = list(map(int, input().split(',')))

# 构建接触关系矩阵
graph = []
for _ in range(n):
    # 将每行的逗号分隔字符串转为整数列表
    row = list(map(int, input().split(',')))
    graph.append(row)

BFS算法实现

from collections import deque

def count_test_needed(n, confirmed, graph):
    # 初始化访问标记数组
    visited = [False] * n
    
    # 创建队列并添加所有确诊病例
    q = deque()
    for c in confirmed:
        visited[c] = True  # 标记已访问
        q.append(c)         # 加入队列
    
    count = 0  # 需要检测的人数(非确诊者)
    
    # 开始BFS遍历
    while q:
        node = q.popleft()  # 取出当前节点
        # 检查所有可能接触者
        for neighbor in range(n):
            # 存在接触且未访问过
            if graph[node][neighbor] == 1 and not visited[neighbor]:
                visited[neighbor] = True  # 标记为已访问
                q.append(neighbor)        # 加入队列继续扩展
                count += 1               # 增加检测人数
    
    return count

结果输出

result = count_test_needed(n, confirmed, graph)
print(result)

算法原理解析

BFS如何工作?

想象一滴墨水滴入水中扩散的过程:

  1. 起始点(确诊病例)作为墨滴中心
  2. 第一层:直接接触者(距离1)
  3. 第二层:间接接触者(距离2)
  4. 以此类推,直到无法继续扩散

为什么使用BFS?

  1. 直观性:按接触距离层级遍历
  2. 高效性:时间复杂度O(N²),N<100完全可行
  3. 避免重复:visited数组保证每人只处理一次
  4. 完整覆盖:确保找出所有可能感染者

关键点说明

  1. 确诊者不计数:起始点加入队列但不增加count
  2. 无向图处理:接触关系是相互的(A接触B则B接触A)
  3. 矩阵解读:graph[i][j]=1表示人员i与j有接触
  4. 多起点支持:多个确诊者自然形成多个搜索起点

实例分析(题目用例)

输入:

5
1,2
1,1,0,1,0
1,1,0,0,0
0,0,1,0,1
1,0,0,1,0
0,0,1,0,1

处理过程:

  1. 确诊人员:1号和2号
  2. 从1号开始:
    • 接触0号(计数+1)
    • 0号接触3号(计数+1)
  3. 从2号开始:
    • 接触4号(计数+1)
  4. 最终计数:3

可视化搜索过程:

确诊者 [1,2]
  |
 1 -> 0 (计数1)
 0 -> 3 (计数2)
  |
 2 -> 4 (计数3)

总结

通过BFS解决人员接触检测问题,展示了算法如何应用于实际场景:

  1. 理解问题本质:图论中的连通分量
  2. 选择合适算法:BFS层级扩展
  3. 注意边界条件:确诊者不计入结果
  4. 实现简洁高效:使用队列和访问标记

这种解题思路不仅适用于疫情防控,还可扩展到社交网络分析、信息传播预测等领域。掌握基础算法思想,就能灵活解决各种现实问题!

你可能感兴趣的:(华为OD机试Python版,华为od,python,开发语言)