题目大意
给定一个长度为 n的数组 a1,a2,…,an。现在,要将该数组从中间截断,得到三个非空子数组。要求,三个子数组内各元素之和都相等。请问,共有多少种不同的截断方法?
数据范围
1≤n≤1e5,−10000≤ai≤10000。
解题思路
分为三个数组,且元素和相等,那么每个数组的元素和为原数组的1/3。不存在分配方案即为(原数组总和)%3!=0的情况。a[]为前缀和,ave=原数组总和/3,我们只需要寻找一个位置 a[i]==ave*2,
此时ans+=(a[1~i-1]==ave)即可,因为第i位满足2*ave,所以只需要加上能使前i位的数组分为两个值为averge的位置的数量即可
AC代码
#include<bits/stdc++.h>
using namespace std ;
int n,ave,a[100005];
long long ans;
long long cnt;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
a[i]+=a[i-1];
}
if(a[n]%3)cout<<0;//如果总和不能整除3,肯定没解
else{
ave=a[n]/3;
for(int i=1;i<n;i++){//要先计算当前的值是否等于2*ave,防止这个数正好等于2*ave又等于ave,多加了本身的结果
if(a[i]==ave*2)ans+=cnt;//如果前i个数的和正好等于2*ave,加上前面等于ave的数量
if(a[i]==ave)cnt++;//如果前i个数的和正好等于ave,cnt++
}
cout<<ans;
}
}