小C的糖果分配问题 | 豆包MarsCode AI刷题

129 阅读3分钟

问题描述

小C有一堆糖果,总共有𝑛颗。她需要将糖果分给小朋友们,每个小朋友的糖果数量必须在𝑙到𝑟之间。她想知道,在满足这些条件的前提下,最少可以分给多少个小朋友,最多可以分给多少个小朋友。如果糖果无法正好分完,返回-1

输入:

  1. n:表示糖果的数量。
  2. l:表示小朋友分到的糖果数量最小值。
  3. r:表示小朋友分到的糖果数量最大值。

输出:

一个数组,第一项为分给小朋友数的最小值,第二项为分给小朋友数的最大值。

(无法正好分完时,为 [-1]

问题分析

如果想要分给最少的小朋友,意味着每个小朋友要分配的糖尽可能多。

如果直接 n / r 可能导致结果是小数(例如10 / 3 = 3.33),在这个时候,由于计算时,每个小朋友分到的糖果数已经是最大值 r 了,意味着我们需要更多的小朋友,即需要4个小朋友(因为不能有部分小朋友),才能保证糖果数能够被分配完。

所以我们使用 math.ceil 向上取整 确保我们至少分配够n颗糖果。

# 最少分配的小朋友数
    min_friends = math.ceil(n / r)

而同理,对于分配最多的小朋友,每个小朋友分到的糖果数是最小值 l 了,所以需要向下取整让有些小朋友多拿一点。

// :地板除,返回除完之后的商的整数部分(向下取整)

# 最多分配的小朋友数
    max_friends = n // l

所需检验的特殊情况:

  • min_friends>max_friends

    极端情况中,如果 rl 相等且都不能被 n 整除,由于最少小朋友数是上取整,最多小朋友数是下取整,导致出现min_friends>max_friends

    例如 n = 12, l = 5, r = 5

    • min_friends = 3(每个小朋友分到 4 颗糖果)
    • max_friends = 2(每个小朋友分到 6 颗糖果)

    所以需要检验,防止返回错误结果。

    if min_friends>max_friends:
            return [-1]
    
  • min_friends * r < n or max_friends * l > n

    1. min_friends * r < n

      如果 min_friends 个小朋友每人分到 r 颗糖果(最多的糖果数量),总糖果数仍然小于 n,说明无法正好分完糖果。

    2. max_friends * l > n

      如果 max_friends 个小朋友每人分到 l 颗糖果(最少的糖果数量),总糖果数仍然大于 n,说明无法正好分完糖果。

    所以这种情况同样需要检验。

min_friendsmax_friends,是一个最小到最大的范围,可以确保的是,在这个区间内的所有candies_per_friend,都有l <= candies_per_friend <= r

由于max_friends * l <= n and max_friends * r > n ,意味着肯定有某种取值组合能让在max_friends 的小朋友数目下,正好分配完。对于 min_friends 也是同理,所以不需要再进行额外的检验,可以直接返回这个结果,这不只是一个可能的范围,而是真正满足题意的最大最小值。

完整代码

import math

def solution(n: int, l: int, r: int) -> list:
    # 最少小朋友数,假设每个小朋友分到最多的 r 颗糖果
    min_friends = math.ceil(n / r)
    
    # 最大小朋友数,假设每个小朋友分到最少的 l 颗糖果
    max_friends = n // l
    
    if min_friends>max_friends:
        return [-1]
    # 如果最少小朋友数的糖果总和大于总糖果数或者最多小朋友数的糖果总和小于总糖果数,则返回 -1
    if min_friends * r < n or max_friends * l > n:
        return [-1]

    return [min_friends, max_friends]


# 测试用例
if __name__ == '__main__':
    print(solution(12, 5, 5) == [-1])
    print(solution(10, 2, 3) == [4, 5])
    print(solution(7, 3, 5) == [2, 2])
    print(solution(8, 1, 4) == [2, 8])  
    print(solution(15, 10, 13) == [-1])  # 返回 -1,因为无法恰好分配