3956. 截断数组

文章描述了一种解决编程问题的方法,涉及数组处理和数学逻辑。当数组总和能被3整除且长度大于2时,可以寻找数组中等于平均值和两倍平均值的位置作为截断点。通过遍历数组,动态更新这两个条件下的截断点数量,最终得到可以均匀截断的组合数。
摘要由CSDN通过智能技术生成

题目链接

链接: 3956. 截断数组

做题思路

读完题,我们可以大致理出一个思路:
sum:给出数组的总合
ave:数组的平均值
1) 当sum%3!=0时,数组一定不能被均匀截断,直接输出0就好了;
2) 再进行判断,由于要将数组截成3段,我们就需要找到两个分割节点,确定了分割节点的个数,就可以直接得出最终答案了

大致思路其实很简单,但是容易在计算最终结果上出错,接下来我们着重分析最终答案的计算方法

核心思路

我们可以一眼看出,可以截断的部分有两个:s==ave和s==2*ave的地方。

我们令res为最终答案,js为s==ave时,可截断的地方

注意:千万不要直接分别统计两种截断点的个数再相乘求解,在sum==0的情况下会出错

我们应该在发现每一个s==2*ave截断点时进行res+=js操作
因为我们发现第二种截断点时,我们都可以与第一种截断点进行组合来截断

再来说说细节问题

遍历范围:
遍历范围我们设置为[0, n-2],我们的截断点为nums[i]后位置,第i个数在数组尾部,所以不存在截断点

先计算res还是js:
由于第一截断点和第二截断点在不同位置时我们才能进行计算,这是我们考虑全是0的特殊情况:此时在同一轮循环中,二者位置可能会重合,我们先计算res再统计js就能成功避免这种情况,代码如下:

for i in range(n-1):
        s+=nums[i]
        if(s==2*ave):
            res+=js
        if(s==ave):
            js+=1

完整AC代码

n = int(input())
nums= [int(i) for i in input().split()]

if(sum(nums)%3!=0 or n<3):
    print(0)
else:
    s = 0
    js=0
    res=0
    ave=sum(nums)//3
    for i in range(n-1):
        s+=nums[i]
        if(s==2*ave):
            res+=js
        if(s==ave):
            js+=1
    print(res)
        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值