华为OD机试_2025 B卷_食堂供餐(Python,100分)(附详细解题思路)

题目描述

某公司员工食堂以盒饭方式供餐。

为将员工取餐排队时间降低为0,食堂的供餐速度必须要足够快。

现在需要根据以往员工取餐的统计信息,计算出一个刚好能达成排队时间为0的最低供餐速度。即,食堂在每个单位时间内必须至少做出多少价盒饭才能满足要求。

输入描述
第1行为一个正整数N,表示食堂开餐时长。

1 ≤ N ≤ 1000
第2行为一个正整数M,表示开餐前食堂已经准备好的盒饭份数。

P1 ≤ M ≤ 1000
第3行为N个正整数,用空格分隔,依次表示开餐时间内按时间顺序每个单位时间进入食堂取餐的人数Pi。

1 ≤ i ≤ N
0 ≤ Pi ≤ 100
输出描述
一个整数,能满足题目要求的最低供餐速度(每个单位时间需要做出多少份盒饭)。

备注
每人只取一份盒饭。
需要满足排队时间为0,必须保证取餐员工到达食堂时,食堂库存盒饭数量不少于本次来取餐的人数。
第一个单位时间来取餐的员工只能取开餐前食堂准备好的盒饭。
每个单位时间里制作的盒饭只能供应给后续单位时间来的取餐的员工。
食堂在每个单位时间里制作的盒饭数量是相同的。
用例

输入 3
14
10 4 5
输出 3
说明

本样例中,总共有3批员工就餐,每批人数分别为10、4、5。


开餐前食堂库存14份。

食堂每个单位时间至少要做出3份餐饭才能达成排队时间为0的目标。具体情况如下:

  1. 第一个单位时间来的10位员工直接从库存取餐。取餐后库存剩余4份盒饭,加上第一个单位时间做出的3份,库存有7份
  2. 第二个单位时间来的4员工从库存的7份中取4份。取餐后库存剩余3份盒饭,加上第二个单位时间做出的3份,库存有6份。
  3. 第三个单位时间来的员工从库存的6份中取5份,库存足够。

如果食堂在单位时间只能做出2份餐饭,则情况如下:

  1. 第一个单位时间来的10位员工直接从库存取餐。取餐后库存剩余4份盒饭,加上第一个单位时间做出的2份,库存有6份
  2. 第二个单位时间来的4员工从库存的6份中取4份。取餐后库存剩余2份盒饭,加上第二个单位时间做出的2份,库存有4份.
  3. 第三个单位时间来的员工需要取5份,但库存只有4份,库存不够。

解题思路:二分法与过程模拟结合

这道题的关键在于找到一个最低的制作速度,使得食堂在每个时间段的盒饭库存都能满足到来的取餐人数。由于题目要求制作速度必须是固定的,所以我们需要找到满足条件的最小整数解。

核心思路分析

我们可以将问题分解为以下三个步骤:

  1. 模拟检查:对于一个给定的制作速度x,模拟整个取餐过程,判断是否能满足所有时间段的需求。
  2. 二分查找:由于制作速度越大越容易满足条件,我们可以用二分法快速找到最小的可行解。
  3. 边界确定:确定二分查找的初始范围,高效地缩小解的可能区间。

逐步拆解问题

步骤一:可行性判断函数

编写函数is_possible(x),参数x代表当前假设的制作速度。函数的逻辑如下:

  1. 初始化库存为开餐前准备好的盒饭数量M。
  2. 遍历每个时间段
    • 若当前库存不足以满足该时间段的需求人数,立即返回False。
    • 扣除相应的盒饭数量,并立即生产x份(这些盒饭供后续时间段使用)。

例如样例输入,当x=3时,处理流程为:

  • 初始库存14 → 处理10人后剩4 → 生产3 → 库存7。
  • 处理4人后剩3 → 生产3 → 库存6。
  • 处理5人后剩1 → 生产3 → 库存4。所有步骤均满足条件,返回True。
步骤二:二分查找最小速度

确定x的可能范围,初始设为left=0right=1e18(足够大的范围确保覆盖所有可能解):

  1. 计算中间值mid,检查mid是否可行。
  2. 若可行,说明可能存在更小的解,缩小右边界。
  3. 否则,必须增大左边界。

这个过程通过不断缩小区间逼近最小值,时间复杂度为O(logN),非常高效。

步骤三:边界处理与终止条件

当左边界超过右边界时,最后一次可行的mid即为最终答案。整个过程确保了在O(NlogC)的时间复杂度内解决问题(C为可能的最大速度值)。

实现代码示例

n = int(input())
m = int(input())
p = list(map(int, input().split()))

def is_possible(x):
    current = m
    for num in p:
        if current < num:
            return False
        current -= num
        current += x
    return True

left = 0
right = 10**18
ans = 0
while left <= right:
    mid = (left + right) // 2
    if is_possible(mid):
        ans = mid
        right = mid - 1
    else:
        left = mid + 1

print(ans)

关键点总结

  1. 实时库存更新:每个时间段处理后立即补充x份,确保后续时间段有足够库存。
  2. 终止条件判断:二分法终止时,左边界指向第一个可行解。
  3. 处理大数范围:初始右边界足够大以保证覆盖所有可能情况。

通过这种思路,我们能够高效且准确地找到最低的制作速度,确保食堂供应充足。这种二分与模拟结合的方法在类似的最优化问题中具有广泛的适用性。

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