华为OD机试_2025 B卷_报文响应时间(Python,100分)(附详细解题思路)

文章目录

  • 题目描述
  • 核心解题思路
      • 关键步骤解析
    • 解题步骤详解
      • 步骤一:解析最大响应时间字段
      • 步骤二:计算每个报文的截止时间
      • 步骤三:维护全局最小截止时间
    • 完整代码实现
    • 总结

题目描述

IGMP 协议中,有一个字段称作最大响应时间 (Max Response Time) ,HOST收到查询报文,解折出 MaxResponsetime 字段后,需要在 (0,MaxResponseTime] 时间 (s) 内选取随机时间回应一个响应报文,如果在随机时间内收到一个新的查询报文,则会根据两者时间的大小,选取小的一方刷新回应时间。
华为OD机试_2025 B卷_报文响应时间(Python,100分)(附详细解题思路)_第1张图片

最大响应时间有如下计算方式:
当 Max Resp Code < 128, Max Resp Time = Max Resp Code;
当 Max Resp Code ≥ 128,

Max Resp Time = (mant | 0x10) << (exp + 3);
注: exp最大响应时间的高5~7位: mant 为最大响应时间的低4位。

其中接收到的MaxRespCode 最大值为 255,以上出现所有字段均为无符号数。

现在我们认为 HOST收到查询报文时,选取的随机时间必定为最大值,现给出 HOST 收到查询报文个数 C,HOST 收到该报文的时间T,以及查询报文的最大响应时间字段值 M,请计算出HOST 发送响应报文的时间。

输入描述
第一行为查询报文个数 C,后续每行分别为 HOST 收到报文时间 T,及最大响应时间M,以空格分割。

输出描述
HOST 发送响应报文的时间。

备注
用例确定只会发送一个响应报文, 不存在计时结束后依然收到查询报文的情况。

用例

输入 3
0 20
1 10
8 20
输出 11
说明

收到3个报文,
第0秒收到第1个报文,响应时间为20秒,则要到0+20=20秒响应;
第1秒收到第2个报文,响应时间为10秒,则要到1+10=11秒响应,与上面的报文的响应时间比较获得响应时间最小为11秒;

第8秒收到第3个报文,响应时间为20秒,则要到8+20=28秒响应,与第上面的报文的响应时间比较获得响应时间最小为11秒;

最终得到最小响应报文时间为11秒

输入 2
0 255
200 60
输出 260
说明

收到2个报文,
第0秒收到第1个报文,响应时间为255秒,则要到(15 | 0x10) << (7 + 3)= 31744秒响应; (mant = 15,exp =7)

第200秒收到第2个报文,响应时间为60秒,则要到200+60-260秒响应,与第上面的报文的响应时间比较获得响应时间最小为260秒:

最终得到最小响应报文时间为260秒

核心解题思路

对于这道题,我们需要根据接收到的多个查询报文中的参数,计算出主机发送响应报文的最早时间。每个报文提供的最大响应时间字段决定了该报文对应的响应截止时间。我们需要在这些截止时间中找到最小的一个作为最终结果。

关键步骤解析

  1. 计算最大响应时间

    • 若字段值 M < 128,则直接作为最大响应时间。
    • M ≥ 128,需按公式 (mant | 0x10) << (exp + 3) 计算。其中 expM 的高三位(通过位运算提取),mantM 的低四位。
  2. 计算截止时间

    • 每个报文的截止时间为接收时间 T 加上对应的最大响应时间。
  3. 维护最小截止时间

    • 遍历所有报文,计算各自的截止时间,并始终保存当前最小的那个。

解题步骤详解

步骤一:解析最大响应时间字段

题目给出的最大响应时间计算分为两种情况:

  1. 当字段值 M < 128
    直接取 M 作为最大响应时间。例如:

    • M = 20 → 最大响应时间为 20 秒。
  2. 当字段值 M ≥ 128
    需要将 M 拆分为高三位 exp 和低四位 mant

    • exp 通过位运算 (M & 0xE0) >> 5 提取。
    • mant 通过位运算 M & 0x0F 提取。
    • 代入公式计算:
      [
      \text{MaxRespTime} = (\text{mant} \mid 0\text{x}10) \ll (\text{exp} + 3)
      ]

举个例子

  • M = 255(二进制 11111111)时:
    • exp = (255 & 0xE0) >> 5 = 7
    • mant = 255 & 0x0F = 15
    • 计算得 (15 | 0x10) << (7+3) = 31 << 10 = 31744 秒。

步骤二:计算每个报文的截止时间

对于每个报文,其截止时间为接收时间 T 加上对应的最大响应时间:
[
\text{截止时间} = T + \text{MaxRespTime}
]

例如

  • 报文接收时间 T = 0M = 255,则截止时间为 0 + 31744 = 31744 秒。

步骤三:维护全局最小截止时间

初始化一个极大值(如 Infinity),遍历所有报文,计算每个截止时间,并持续更新最小值。最终的最小值即为答案。

示例分析

  • 输入:
    2
    0 255
    200 60
    
  • 处理过程:
    • 第一个报文截止时间为 31744
    • 第二个报文截止时间为 200 + 60 = 260
    • 最小值更新为 260,最终输出 260

完整代码实现

c = int(input())
min_time = float('inf')

for _ in range(c):
    t, m = map(int, input().split())
    if m < 128:
        max_resp = m
    else:
        exp = (m & 0xe0) >> 5
        mant = m & 0x0f
        max_resp = (mant | 0x10) << (exp + 3)
    current_time = t + max_resp
    if current_time < min_time:
        min_time = current_time

print(min_time)

总结

本题的关键在于正确处理最大响应时间的计算,并通过遍历维护最小截止时间。位运算的使用是核心技巧,需特别注意 expmant 的提取方式。最终只需在所有截止时间中取最小值即可得到答案。

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