本次博客我是通过Notion软件写的,转md文件可能不太美观,大家可以去我的博客中查看:北天的 BLOG,持续更新中,另外这是我创建的编程学习小组频道,想一起学习的朋友可以一起!!!
现在,要将该数组从中间截断,得到三个非空子数组。
要求,三个子数组内各元素之和都相等。
请问,共有多少种不同的截断方法?
输入格式
第一行包含整数n。
第二行包含n个整数a1, a2,… . , an。
输出格式
输出一个整数,表示截断方法数量。
数据范围
前六个测试点满足1≤n≤10。
所有测试点满足1≤ 输入样例1: 输出样例1: 输入样例2: 输出样例2: 输入样例3: 输出样例3: 通过使用前缀和,我们可以在O(n)的时间复杂度内解决此问题。 什么是前缀和? 前缀和是一种数学技巧,用于快速求出一个数组的前缀和。前缀和数组定义为:对于数组a中的每个元素a[i],前缀和数组prefix[i]表示a[0]到a[i]的和。 例如,对于数组a=[1, 2, 3, 4, 5],前缀和数组prefix为[1, 3, 6, 10, 15]。 使用前缀和数组可以在O(1)的时间复杂度内查询数组中某一段元素的和,而不需要重新遍历数组。这在很多题目中,如区间求和,有很多应用。4
1 2 3 3
1
5
1 2 3 4 5
0
2
0 0
0
二、解题思路
三、代码实现
def cut(n, nums):
# 判断数组元素个数是否小于3,若是则不存在可行解,直接返回0
if n < 3:
return 0
# 求数组元素和
s = sum(nums)
# 判断数组元素和是否为3的倍数,若不是则不存在可行解,直接返回0
if s % 3 != 0:
return 0
# 将数组元素和除以3,得到每段的平均值
avg = s // 3
# 初始化cnt数组,用于存储每个前缀的符合要求的数量
cnt = [0] * (n + 1)
# 初始化presum数组,用于存储每个前缀的元素和
presum = [0] * (n + 1)
# 枚举每个前缀,计算元素和
for i in range(1, n + 1):
presum[i] = presum[i - 1] + nums[i - 1]
# 枚举每个前缀,判断元素和是否为2倍的平均值
for i in range(1, n):
if presum[i] == avg * 2:
cnt[i] = 1
# 枚举每个前缀,累加符合要求的数量
for i in range(1, n):
cnt[i] += cnt[i - 1]
# 初始化结果为0
res = 0
# 枚举每个前缀,判断元素和是否为平均值
for i in range(n - 2):
if presum[i + 1] == avg:
res += cnt[n - 1] - cnt[i + 1]
# 返回结果
return res
n = int(input().strip())
nums = list(map(int, input().strip().split()))
print(cut(n, nums))