AI刷题笔记 | 豆包MarsCode AI 刷题

66 阅读4分钟

题目:绿洲之旅:最少次数补给探索

小U正在准备穿越一片广阔的沙漠。沙漠里有多个绿洲,每个绿洲设有补给站。所有补给站的收费相同,但提供的水是不同。从起点到终点共有(D)公里,小U需要规划在哪 些补给站停留,以保证整个旅途中水的供应 起点到终点的距离为 D)公里,小U初始携带 ) 升水,每行走1公里消耗1升水,小U希望涌过最少的补给次数安全到认终点,每个补给站的位置电 positioni1 表示,距 离起点的公里数,supply[i]表示该站可以提供的水量,单位为升。 请你帮助小U计算,要安全到达终点至少需要补给几次,或者判断是否根本无法到达终点,此时输出-1。

题目分析

小U需要穿越一片沙漠,起点和终点之间的距离为 𝐷 D 公里,每行走 1 公里消耗 1 升水。小U初始携带 𝑊 W 升水,沙漠中有多个补给站,每个补给站在不同的位置提供不同的水量。小U希望通过最少的补给次数安全到达终点。

输入

  • 𝐷:终点到起点的总距离。
  • 𝑊:小U初始携带的水量。
  • position:一个数组,表示每个补给站距离起点的公里数。
  • supply:一个数组,与 position 对应,表示每个补给站可以提供的水量。

输出##

  • 到达终点所需的最少补给次数。如果无法到达终点,则输出 -1。

题目特点

  • 贪心策略可以解决本问题。
  • 每次选择最优的补给站(提供最多水量)以减少补给次数。
  • 若当前水量不足以支持前进,必须回退到前一个能补充水量的绿洲。

解题思路

思路概述

本题适合用贪心算法解决,整体思路如下:

  1. 模拟小U从起点向终点行进的过程。
  2. 当前水量不足以到达下一个补给站时,从已经路过的补给站中选择提供最多水量的站进行补给。
  3. 在遍历所有补给站后,再检查是否能直接从最后一个补给站到达终点。
  4. 若在任何情况下无法获得足够的水量以继续前进,则返回 -1。

贪心核心点

每次补给时选择当前可用补给站中提供最多水量的站,使用最大堆(优先队列)来实现这个需求。

关键步骤

  1. 初始化数据结构: 使用一个最大堆存储已经路过的补给站的水量。
  2. 遍历补给站
  • 计算当前水量能否支持小U到达下一个补给站。
  • 如果不能,反复从最大堆中取出最大的水量进行补给,直到可以到达下一个站或无法补给为止。
  1. 特殊情况处理
  • 在到达终点之前,若当前水量仍然不足以支持小U到达终点,继续补给;若无水可补则返回 -1。
  1. 返回结果: 输出最少的补给次数。

关键代码解析

初始化变量

def solution(d, w, position, supply):
    # 初始化最大堆
    max_heap = []
    heapq.heapify(max_heap)

current_water 表示当前剩余的水量。

current_position 表示小U当前所在的位置。

refills 记录补给次数。

遍历补给站

    for i in range(len(position)):
        distance_to_next = position[i] - current_position

计算到下一个补给站的距离 distance_to_next。 检查当前水量是否足够:

        while current_water < distance_to_next:
            if not max_heap:
                return -1
            current_water += -heapq.heappop(max_heap)
            refills += 1

如果当前水量不足,则从 max_heap 中取出最大的水量进行补给。

如果堆为空且水量仍不足,返回 -1。

更新状态

        current_water -= distance_to_next
        current_position = position[i]
        heapq.heappush(max_heap, -supply[i])

更新当前水量和位置。

将当前补给站的水量压入堆中。

检查是否能到达终点

    distance_to_end = d - current_position
    while current_water < distance_to_end:
        if not max_heap:
            return -1
        current_water += -heapq.heappop(max_heap)
        refills += 1

到达所有补给站后,如果仍无法到达终点,继续从堆中补给水量。

复杂度分析

时间复杂度: 𝑂 ( 𝑁 log ⁡ 𝑁 ) O(NlogN),其中 𝑁 N 是补给站的数量,每次堆操作为 𝑂 ( log ⁡ 𝑁 ) O(logN)。

空间复杂度: 𝑂 ( 𝑁 ) O(N),用于存储最大堆。

总结

  • 本题利用贪心策略选择每次补给的最优站点,结合最大堆实现。
  • 关键在于正确管理当前水量和遍历逻辑。
  • 对于需要优先选择最大值的场景,最大堆是高效解决方案。