问题描述
在唐门,外门弟子唐三发现了一种强大的暗器技巧,名为暴雨梨花针,它能在一条直线上摧毁所有目标。唐三在一本古籍中学习到了这门技巧,为了练习,他设置了若干个靶子在二维平面上。每个靶子是一条垂直于X轴的线段,由三个参数 x_{left},x_{right},y 描述,其中 y 是固定的高度,x_{left} 和 x_{right} 表示线段在X轴上的起止位置。
唐三的目标是使用尽可能少的暴雨梨花针来击中所有靶子。由于暴雨梨花针的珍贵,每次射击必须经济有效。每次射击暴雨梨花针都将从某个 x 值发射,能垂直上升到 y = 100。
请你帮助唐三计算最少需要多少次射击,才能保证击中所有靶子。结果需对给定的 P 取余。
这题的主要解法是通过排序后逐层处理,确保每一次都能打到尽可能多的针,因为最左边(或最右边)的靶子一定是我们的起点,如果他的右端点包含其他的靶子的左端点,既能使其高效
-
排序逻辑:
- 你需要按照靶子的
x_left进行排序,这样可以确保我们优先处理左端点较小的靶子。
- 你需要按照靶子的
-
覆盖逻辑:
- 使用一个变量
current_end来跟踪当前针的覆盖范围。如果下一个靶子的左端点x_left超过了current_end,则需要发射新的针。 - 在更新
current_end时,考虑当前靶子的x_right和current_end的最大值。
- 使用一个变量
-
返回结果:
- 返回
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
代码逻辑分析:
-
排序:首先,代码对
target列表中的靶子按照它们的右边界x_right进行排序。这是为了确保在处理靶子时,能够按顺序尽可能地用一根针覆盖多个相邻的靶子。 -
初始化变量:
needles用于记录所需的针的数量,current_end用于记录当前针能够覆盖到的最远位置。 -
遍历靶子:对于
target列表中的每个靶子,检查其左边界x_left是否在当前针的覆盖范围内(即x_left是否大于current_end)。- 如果不在当前针的覆盖范围内,说明需要一根新的针来覆盖这个靶子。因此,
needles加一,并更新current_end为当前靶子的右边界x_right。 - 如果在当前针的覆盖范围内,则不需要额外的针,继续检查下一个靶子。
- 如果不在当前针的覆盖范围内,说明需要一根新的针来覆盖这个靶子。因此,
-
返回结果:最后,返回所需的针的数量对
p取模的结果。