读题,发糖规则为逐个递增分发,发现分发的糖果成等差数列,最后的(不够继续分的)需特殊讨论。
思考要怎么做——前面的完整分发轮次和后面的不完整分发轮次分开。
出现新的问题,怎么知道有多少完整的轮次——row?
注意,要求多少轮,不是用糖数整除人数(平均分)求出,而是用利用数列元素数整除人数,加之不等式以及等差数列求和得出。
那我们利用谁来进行不等式?——剩余糖数——大于0,小于p+1
C表示总糖数,p(1+p)/2表示前 p项和,相减得到剩余糖数。
Sn=n(a1+an)/2=na1+n(n-1)d/2
下面就利用不等式的相关性质计算不等式。
注意,计算到p(p+1)时,通过把不等式拆成两个不等式解出p的范围。
p只能取整数
row=p//n (数列元素数整除人数)
求出非完整回合有多少个 ?——col
col=p%n
解决了关键问题之后,后面的就可以之间用for循环+if判断完成
定义列表,后面采取列表的替换,初始定义为0,有n个元素
d=[0]*n
后面如果是能在完整回合分发结束时,即首项为i+1,公差为n(人),总共有row项
d[i]=row*(i+1)+row*(row-1)*n*0.5
若在非完整回合才分发结束,即需要再加上第(row+1)项
an=a1+(n-1)d
d[i]+=(i+1)+row*n
对于最后剩下的不能完整分发的,把他加给最后一个人,即第(col+1)个人,即d[col]
注意,col指的是完整数列的元素
d[col]+=r
补充求一下数列外剩下的
r=C-p*(1+p) *0.5
完整代码如下
class Solution:
def distributeCandies(self, candies: int, num_people: int) -> List[int]:
n = num_people
c = candies
p = int((2 * c + 0.25) ** 0.5 - 0.5)
r = int(c - (p + 1) * p * 0.5)
row = p // n
col = p % n
d = [0] * n
for i in range(n): # 只循环n次
# 完整循环回合
d[i] = int(row * (i + 1) + row * (row - 1) * n * 0.5) # 等差数列公式
# 非完整回合的恰当分发
if i < col:
d[i] += int(row * n + i + 1)
# 最后剩下的加到最后一项
d[col] += r
return d