华为OD机试_2025 B卷_人数最多的站点(Python,100分)(附详细解题思路)

文章目录

  • 题目描述
  • 人数最多站点问题:巧用差分数组(解法一)
    • 核心解题思路
    • 算法步骤
    • 完整代码实现
    • 代码解析
    • 示例验证
    • 常见疑问解答
    • 总结
  • 小火车乘客最多站点问题:简单直观的解法(解法二)
    • 核心思路:模拟火车运行过程
    • 为什么这个方法更简单?
    • 完整代码实现
    • 示例推演
    • 常见问题解答
      • Q:为什么站点2人数是3?
      • Q:相同人数怎么办?
      • Q:站点不连续怎么办?
      • Q:为什么用字典不用数组?
    • 总结

题目描述

公园园区提供小火车单向通行,从园区站点编号最小到最大通行如12341,然后供员工在各个办公园区穿梭,通过对公司N个员工调研统计到每个员工的坐车区间,包含前后站点,请设计一个程序计算出小火车在哪个园区站点时人数最多。

输入描述
第1个行,为调研员工人数

第2行开始,为每个员工的上车站点和下车站点。
使用数字代替每个园区用空格分割,如3 5表示从第3个园区上车,在第5个园区下车

输出描述
人数最多时的园区站点编号,最多人数相同时返回编号最小的园区站点

用例

输入 3
1 3
2 4
1 4
输出 2
说明

人数最多站点问题:巧用差分数组(解法一)

核心解题思路

作为初学者,当我们遇到统计区间内人数变化的问题时,最直观的想法可能是遍历每个站点,计算每个站点的实时人数。但这种方法的时间复杂度是O(n²),当站点数量大时效率很低。这里介绍一种更高效的解法:差分数组 + 前缀和

核心思想

  1. 火车到达每个站点时,先让下车的乘客离开,再让上车的乘客进入
  2. 使用两个字典分别记录每个站点的上车人数下车人数
  3. 通过有序遍历所有站点,动态计算车上人数
  4. 在遍历过程中记录人数最多的站点(人数相同时取编号最小的)

为什么这个方法高效

  • 只处理实际存在的站点,避免无效遍历
  • 每个站点只处理一次,时间复杂度O(m log m)(m为站点数量)
  • 空间复杂度O(m),只需存储站点信息

算法步骤

  1. 处理输入

    • 读取员工数量
    • 读取每个员工的上下车站点
  2. 数据预处理

    • 创建字典记录每个站点的上车/下车人数
    • 收集所有站点并排序
  3. 模拟火车运行

    • 初始化当前车上人数为0
    • 按站点编号从小到大遍历:
      • 先减去该站点的下车人数
      • 再加上该站点的上车人数
      • 更新最大人数记录
  4. 输出结果

    • 返回人数最多且编号最小的站点

完整代码实现

# 输入部分
n = int(input().strip())

# 处理0员工情况
if n == 0:
    print(0)
    exit()

onboard = {}
offboard = {}
stations_set = set()

# 读取每个员工的上下车站点
for _ in range(n):
    data = input().split()
    if len(data) < 2:
        continue
    a = int(data[0])
    b = int(data[1])
    onboard[a] = onboard.get(a, 0) + 1
    offboard[b] = offboard.get(b, 0) + 1
    stations_set.add(a)
    stations_set.add(b)

# 主体函数
def find_max_station():
    # 获取所有站点并排序
    stations = sorted(stations_set)
    
    current_people = 0
    max_people = 0
    max_station = stations[0]  # 初始化为第一个站点
    
    for station in stations:
        # 先下车
        if station in offboard:
            current_people -= offboard[station]
        # 再上车
        if station in onboard:
            current_people += onboard[station]
        
        # 更新最大人数记录
        if current_people > max_people:
            max_people = current_people
            max_station = station
    
    return max_station

# 输出结果
result = find_max_station()
print(result)

代码解析

  1. 输入处理

    • 第一行读取员工数量
    • 处理特殊情况:0员工直接返回0
  2. 数据存储

    • onboard字典:记录每个站点的上车人数
    • offboard字典:记录每个站点的下车人数
    • stations_set:收集所有出现过的站点
  3. 核心算法

    • 对所有站点排序,确保从小到大处理
    • 遍历每个站点时:
      • 先减去下车人数(模拟乘客离开)
      • 再加上上车人数(模拟乘客进入)
    • 动态更新最大人数记录
  4. 边界处理

    • 当站点没有上车/下车人数时自动跳过
    • 人数相同时自动保留编号更小的站点

示例验证

以题目用例验证:

输入:
3
1 3
2 4
1 4

处理过程:
onboard = {1:2, 2:1}
offboard = {3:1, 4:2}
stations = [1, 2, 3, 4]

站点10 + 2 = 2
站点22 + 1 = 3 → 更新最大人数
站点33 - 1 = 2
站点42 - 2 = 0

输出:2(正确)

常见疑问解答

Q:为什么先下车再上车?
A:这符合实际乘车流程:火车到站后,先下后上

Q:站点编号不连续怎么办?
A:算法只处理实际存在的站点,自动跳过中间站点

Q:多人同时上下车如何处理?
A:字典会累加每个站点的总上下车人数

Q:时间复杂度如何?
A:O(m log m),其中m是站点数量(不超过2n)

总结

通过这个题目,我们学习了:

  1. 使用字典高效存储数据
  2. 差分数组处理区间统计问题
  3. 有序遍历确保结果正确性
  4. 边界条件的全面考虑

这种方法不仅适用于本题,还可扩展到其他区间统计问题,如会议室安排、公交调度等。核心是抓住事件发生点(上下车点),通过有序处理这些点来高效计算状态变化。

小火车乘客最多站点问题:简单直观的解法(解法二)

核心思路:模拟火车运行过程

最直观的解法是模拟火车从起点到终点的运行过程,在每个站点记录上下车情况:

  1. 确定站点范围

    • 找出所有出现过的站点
    • 按从小到大排序
  2. 模拟运行

    • 从最小站点开始,依次访问每个站点
    • 在每个站点:
      • 先让到站的乘客下车
      • 再让新乘客上车
      • 记录当前车上人数
  3. 记录最大值

    • 比较每个站点离开时的人数
    • 记录人数最多的站点(相同人数取较小站点)

为什么这个方法更简单?

  1. 符合现实逻辑:像真正的小火车一样一站站前进
  2. 无需高级概念:只用基本数组和循环
  3. 直观易懂:每个步骤都有明确的现实对应
  4. 效率足够:站点数量不超过员工数×2,10000员工→20000站点,完全可处理

完整代码实现

# 输入部分
n = int(input().strip())

# 处理特殊情况:没有员工
if n == 0:
    print(0)
    exit()

# 存储上下车信息
get_on = {}  # 记录每个站点上车人数
get_off = {}  # 记录每个站点下车人数
stations = set()  # 收集所有站点

# 读取每个员工的行程
for _ in range(n):
    data = input().split()
    start = int(data[0])
    end = int(data[1])
    
    # 记录上车信息
    if start in get_on:
        get_on[start] += 1
    else:
        get_on[start] = 1
    
    # 记录下车信息
    if end in get_off:
        get_off[end] += 1
    else:
        get_off[end] = 1
    
    # 记录站点
    stations.add(start)
    stations.add(end)

# 将站点排序(从小到大)
sorted_stations = sorted(stations)

# 模拟火车运行
current_passengers = 0  # 当前车上人数
max_passengers = 0  # 最大人数
max_station = sorted_stations[0]  # 人数最多的站点

for station in sorted_stations:
    # 本站有乘客下车
    if station in get_off:
        current_passengers -= get_off[station]
    
    # 本站有乘客上车
    if station in get_on:
        current_passengers += get_on[station]
    
    # 更新最大人数记录(注意:比较在乘客上车后)
    if current_passengers > max_passengers:
        max_passengers = current_passengers
        max_station = station

# 输出结果
print(max_station)

示例推演

用题目案例演示:

输入:3
行程:1→3, 2→4, 1→4

处理过程:

站点 下车人数 上车人数 当前人数 是否新高
1 0 2 2 是(2)
2 0 1 3 是(3)
3 1 0 2
4 2 0 0

输出:站点2(人数3)

常见问题解答

Q:为什么站点2人数是3?

A:在站点2,火车带着站点1上车的2人到达,没有人下车(他们都在后续站点下车),然后1名新乘客上车,共3人。

Q:相同人数怎么办?

A:代码中if current_passengers > max_passengers使用大于号,所以只在新高时更新站点。相同人数时保持之前的较小站点。

Q:站点不连续怎么办?

A:排序后的站点可能不连续(如1,3,5),但模拟过程会跳过中间站点,因为中间没有上下车事件。

Q:为什么用字典不用数组?

A:字典更灵活,不需要预先分配大数组,只需存储实际有事件的站点。

总结

通过这个解法我们学习到:

  1. 复杂问题简单化:用现实模拟代替抽象算法
  2. 合理选择数据结构:字典和集合处理稀疏数据
  3. 分步解决问题
    • 收集数据
    • 排序站点
    • 模拟运行
    • 记录结果
  4. 边界情况处理:没有员工、单个员工等特殊情况

这种方法直观易懂,适合初学者理解和实现。核心思想是"像真正的小火车一样一站站前进",通过简单计数解决看似复杂的问题。

你可能感兴趣的:(华为OD机试Python版,华为od,python,算法)