AI 刷题 293.粮食分配的可能性计算 题解 | 豆包MarsCode AI刷题

148 阅读3分钟

293.粮食分配的可能性计算

问题描述

粮食公司需要将nn吨粮食分配给若干分销商,每个分销商能够获得的粮食数量等于将nn除以分销商数量,向下取整。问题是,计算在可能的分销商数量中,分销商获得的不同粮食数量有多少种可能。

思路解析

  • 整体目标
    给定总粮食吨数 n,需要找出在不同分销商数量情况下,每个分销商所能获得粮食数量的不同可能性的种数。核心思路是通过遍历所有可能的分销商数量,计算出对应的每个分销商分得的粮食数量,再利用集合去重的特性,统计出不同分配数量的种类。
  • 利用整数除法向下取整
    根据题目规则,每个分销商能够获得的粮食数量等于将 n 除以分销商数量,向下取整(通过 // 运算符实现)。例如,总共有 10 吨粮食,如果有 3 个分销商,那么每个分销商分得的粮食就是 10 // 3 = 3 吨(向下取整)。通过这样的计算方式,能得到不同分销商数量下对应的分配结果。
  • 使用集合去重
    因为我们关心的是不同的分配数量有多少种,所以利用 Python 中集合(set)的特性,集合中的元素具有唯一性,将每次计算出来的分配数量添加到集合中,这样集合最终包含的元素个数就是不同分配方案的数量,也就是我们要求的结果。

解题步骤

  1. 初始化集合: 创建一个空集合 unique_allocations,用于存储不同的粮食分配方案(即每个分销商获得的粮食数量)。
  2. 遍历可能的分销商数量: 使用 for 循环遍历从 1 到 n 的所有整数,这里的每个整数 k 代表一种可能的分销商数量情况。例如,当 n = 5 时,会依次考虑分销商数量为 1、2、3、4、5 这几种情况。
  3. 计算并添加分配方案到集合 在每次循环中,首先通过 n // k 计算出当前分销商数量 k 下每个分销商能获得的粮食数量 allocation(利用整数除法向下取整)。然后将这个计算得到的分配数量 allocation 添加到 unique_allocations 集合中。由于集合的去重特性,如果之前已经添加过相同的分配数量,这次添加操作不会重复添加该元素到集合里。
  4. 返回不同分配方案的数量: 循环结束后,集合 unique_allocations 中已经包含了所有不同的分配数量,通过 len(unique_allocations) 获取集合中元素的个数,也就是不同分配方案的数量,并将这个数量作为函数的返回值返回,完成整个计算过程。

复杂度分析

  • 时间复杂度: 函数里有个从 1 到 n 的循环,循环执行 n 次,每次循环里做的操作花费时间基本固定,所以整体时间复杂度就是 O(n)
  • 空间复杂度: 主要看存储不同分配方案的集合,最坏情况集合里元素个数和 n 一样多,其他临时变量占空间不大,所以空间复杂度也是 O(n)

Code

def solution(n: int) -> int:
    # 使用集合来存储不同的分配方案
    unique_allocations = set()
    
    # 遍历所有可能的分销商数量
    for k in range(1, n + 1):
        # 计算每个分销商数量下的分配方案
        allocation = n // k
        # 将分配方案加入集合
        unique_allocations.add(allocation)
    
    # 返回集合的大小,即不同的分配方案数量
    return len(unique_allocations)

if __name__ == '__main__':
    print(solution(5) == 3)
    print(solution(7) == 4)
    print(solution(10) == 5)