唐门绝技;暴雨梨花针最少发射次数|豆包MarsCode AI刷题

108 阅读3分钟

问题描述

在唐门,外门弟子唐三发现了一种强大的暗器技巧,名为暴雨梨花针,它能在一条直线上摧毁所有目标。唐三在一本古籍中学习到了这门技巧,为了练习,他设置了若干个靶子在二维平面上。每个靶子是一条垂直于X轴的线段,由三个参数 x_{left}x_{right}y 描述,其中 y 是固定的高度,x_{left} 和 x_{right} 表示线段在X轴上的起止位置。

唐三的目标是使用尽可能少的暴雨梨花针来击中所有靶子。由于暴雨梨花针的珍贵,每次射击必须经济有效。每次射击暴雨梨花针都将从某个 x 值发射,能垂直上升到 y = 100

请你帮助唐三计算最少需要多少次射击,才能保证击中所有靶子。结果需对给定的 P 取余。

这题的主要解法是通过排序后逐层处理,确保每一次都能打到尽可能多的针,因为最左边(或最右边)的靶子一定是我们的起点,如果他的右端点包含其他的靶子的左端点,既能使其高效

  1. 排序逻辑

    • 你需要按照靶子的 x_left 进行排序,这样可以确保我们优先处理左端点较小的靶子。
  2. 覆盖逻辑

    • 使用一个变量 current_end 来跟踪当前针的覆盖范围。如果下一个靶子的左端点 x_left 超过了 current_end,则需要发射新的针。
    • 在更新 current_end 时,考虑当前靶子的 x_right 和 current_end 的最大值。
  3. 返回结果

    • 返回 needles % p,这是符合题目要求的。
def solution(k, p, target):
    # Please write your code here
    target.sort(key=lambda x: x[1])
    
    needles = 0
    current_end = -1
    
    for target in target:
        x_left, x_right, y = target
        # 如果当前靶子的起点在当前覆盖终点之后,说明需要新的针
        if x_left > current_end:
            needles += 1
            current_end = x_right  # 用新针覆盖到当前靶子的终点
    
    return needles % p

代码逻辑分析:

  1. 排序:首先,代码对 target 列表中的靶子按照它们的右边界 x_right 进行排序。这是为了确保在处理靶子时,能够按顺序尽可能地用一根针覆盖多个相邻的靶子。

  2. 初始化变量needles 用于记录所需的针的数量,current_end 用于记录当前针能够覆盖到的最远位置。

  3. 遍历靶子:对于 target 列表中的每个靶子,检查其左边界 x_left 是否在当前针的覆盖范围内(即 x_left 是否大于 current_end)。

    • 如果不在当前针的覆盖范围内,说明需要一根新的针来覆盖这个靶子。因此,needles 加一,并更新 current_end 为当前靶子的右边界 x_right
    • 如果在当前针的覆盖范围内,则不需要额外的针,继续检查下一个靶子。
  4. 返回结果:最后,返回所需的针的数量对 p 取模的结果。