You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

n颗糖果分配给3个孩子的合规分配方式计数及Python代码优化与列表推导式修正求助

优化糖果分配问题的Python代码与列表推导式修复

嘿,我来帮你搞定这个问题!作为编程新手,你能自己写出代码已经很棒了,咱们一步步来优化它,顺便把列表推导式的问题解决掉。

先理清楚问题本质

首先,咱们先明确需求:把n颗糖果分给3个孩子,要求每个孩子至少1颗,且至少有一个孩子的糖果数比另外两个都多。其实换个角度想,这个需求等价于:所有满足“每个孩子至少1颗”的分配方式,减去“三个孩子糖果数完全相等”的情况(只有当n是3的倍数时才存在这1种情况)。

比如n=6时,总共有10种“每个孩子至少1颗”的分配方式,去掉(2,2,2)这1种,剩下的9种就是有效解,和你举的例子一致。

原代码的问题分析

你的原代码有几个可以优化的点:

  • 三重循环效率太低:遍历所有i、j、k从1到n,大部分组合都不满足i+j+k=n,完全是浪费计算资源。
  • 排列去重逻辑冗余:你用itertools.permutations生成排列再去重,最后还把这些排列组存到列表里再展开,逻辑绕了弯路,而且容易出错。
  • 条件判断可以简化(i!=j or j!=k)其实和not (i==j==k)是一个意思,但原代码的去重逻辑导致重复添加或遗漏。

优化后的代码(含正确的列表推导式)

我们可以直接用列表推导式生成所有符合要求的有序分配方式(因为分给不同的孩子,(1,4,1)和(4,1,1)是不同的有效方式):

n = int(input())

# 方式1:直接生成所有有效有序分配(高效简洁)
valid_distributions = [
    (i, j, n - i - j)
    for i in range(1, n - 1)
    for j in range(1, n - i)
    if not (i == j == n - i - j)
]

# 打印结果
print("所有有效分配方式:")
for dist in valid_distributions:
    print(dist)
print(f"总共有 {len(valid_distributions)} 种方式")

代码解释:

  • 我们只遍历满足i >=1j >=1i+j <n的组合,因为k = n-i-j必须至少为1,这样直接过滤掉了绝大多数无效组合。
  • if not (i == j == n - i - j)用来排除三个孩子糖果数完全相等的情况,正好满足需求。

另一种优化思路:先找基础模式再生成排列

如果想先找出不重复的“分配模式”(比如把(1,1,4)、(1,4,1)、(4,1,1)看作同一个基础模式),再生成所有排列,这种方式在n较大时效率更高:

import itertools

n = int(input())

# 第一步:生成无重复的基础分配模式(不考虑孩子顺序)
base_patterns = set()
for i in range(1, n//3 + 1):
    for j in range(i, (n - i)//2 + 1):
        k = n - i - j
        if k >= j and not (i == j == k):
            base_patterns.add((i, j, k))

# 第二步:生成每个基础模式的所有唯一排列
valid_distributions = []
for pattern in base_patterns:
    perms = set(itertools.permutations(pattern))
    valid_distributions.extend(perms)

# 可选:给结果排序,方便查看
valid_distributions = sorted(valid_distributions)

# 打印结果
print("所有有效分配方式:")
for dist in valid_distributions:
    print(dist)
print(f"总共有 {len(valid_distributions)} 种方式")

为什么你的列表推导式出错?

你写的列表推导式逻辑混乱,主要问题是:

  1. 把条件判断和元素生成混在了一起,语法错误。
  2. 在列表推导式里引用arr(还没生成的列表),这在Python里是不允许的,因为arr在推导式执行时还不存在。
  3. 多余的排列去重操作,导致逻辑绕远路。

咱们上面的列表推导式已经完美解决了这个问题,直接生成所有有效分配,不需要额外的去重操作。

内容的提问来源于stack exchange,提问作者Shubham Nanche

火山引擎 最新活动