Abh*_*ury 7 python algorithm math numbers
假设我有一个数字100,需要将其分成 N 份,每份最初不应超过 30。因此初始分组为 (30,30,30)。余数(即 10)将通过连续向每个组添加 2 来分配到这三个组中,从而确保每个组都是 2 的倍数。因此,所需的输出应类似于 (34,34,32)。
注意:原始数字始终是偶数。
我尝试用 Python 解决这个问题,这就是我想到的。显然它并没有按照我想象的方式工作。它通过向每个组迭代添加 1(而不是根据需要添加 2)来分配余数。
num = 100
parts = num//30 #Number of parts into which 'num' is to be divided
def split(a, b):
result = ([a//b + 1] * (a%b) + [a//b] * (b - a%b))
return(result)
print(split(num, parts))
Run Code Online (Sandbox Code Playgroud)
输出:
[34, 33, 33]
Run Code Online (Sandbox Code Playgroud)
期望的输出:
[34, 34, 32]
Run Code Online (Sandbox Code Playgroud)
首先,让我们先简化一下您的问题。忘记 2 的倍数吧。想象一下,您想要将一个非必然偶数n分成k非必然偶数部分。
显然,最平衡的解决方案是有些部分是n // k,有些部分是n // k + 1。
其中有多少个?我们r用 来称呼零件的数量n // k + 1。然后是 的k - r部分n // k,所有部分的总和为:
(n // k) * (k - r) + (n // k + 1) * r
== (n // k) * (k - r) + (n // k) * r + r
== (n // k) * (k - r + r) + r
== (n // k) * k + r
Run Code Online (Sandbox Code Playgroud)
但各部分之和应为n,因此我们需要找到r这样的:
n == (n // k) * k + r
Run Code Online (Sandbox Code Playgroud)
令人高兴的是,您可能会在这里认识到欧几里得除法,其中n // k商为商,r余数为。
这给了我们我们的split功能:
(n // k) * (k - r) + (n // k + 1) * r
== (n // k) * (k - r) + (n // k) * r + r
== (n // k) * (k - r + r) + r
== (n // k) * k + r
Run Code Online (Sandbox Code Playgroud)
测试:
n == (n // k) * k + r
Run Code Online (Sandbox Code Playgroud)
现在回到你的split_even问题。现在我们有了通用函数split,一个简单的解决方法split_even是使用split:
def split(n, k):
d,r = divmod(n, k)
return [d+1]*r + [d]*(k-r)
Run Code Online (Sandbox Code Playgroud)
测试:
print( split(50, 3) )
# [17, 17, 16]
Run Code Online (Sandbox Code Playgroud)
mm对 2 以外的数字的倍数做同样的事情是很简单的:
def split_even(n, k):
return [2 * x for x in split(n // 2, k)]
Run Code Online (Sandbox Code Playgroud)
测试:
print( split_even(100, 3) )
# [34, 34, 32]
Run Code Online (Sandbox Code Playgroud)