【Python】练习:分糖果Ⅱ

读题,发糖规则为逐个递增分发,发现分发的糖果成等差数列,最后的(不够继续分的)需特殊讨论。

思考要怎么做——前面的完整分发轮次和后面的不完整分发轮次分开。

出现新的问题,怎么知道有多少完整的轮次——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

  • 13
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值