题目链接
链接: 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)