给定一个长度为 n 的数组 a1,a2,…,an。
现在,要将该数组从中间截断,得到三个非空子数组。
要求,三个子数组内各元素之和都相等。
请问,共有多少种不同的截断方法?
输入格式
第一行包含整数 n。
第二行包含 n个整数 a1,a2,…,an。
输出格式
输出一个整数,表示截断方法数量。
数据范围
前六个测试点满足 1≤n≤10。
所有测试点满足 1≤n≤100000,−10000≤ai≤100000。
输入样例1:
4 1 2 3 3
输出样例1:
1
输入样例2:
5 1 2 3 4 5
输出样例2:
0
输入样例3:
2 0 0
输出样例3:
0
分析:
构建前缀和数组,首先数组和a[n]应该满足a[n]能整除3,否则不满足条件。然后可以用cnt计数计算等于a[n]/3的所有不同段,当出现a[i]满足a[i]=a[n]/3时,则之前所有的等于a[n]/3的段都可以满足,总数sum加上cnt来计算总和,实现求解。由于数据范围很大,方案会有很多,所有需要对答案开long long。
代码:
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int a[N];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
a[i]+=a[i-1];
}
if(a[n]%3) printf("0");
else
{
ll sum=0;
int cnt=0;
for(int i=2;i<n;i++)
{
if(a[i-1]==a[n]/3) cnt++;
if(a[i]==a[n]/3*2) sum+=cnt;
}
printf("%lld",sum);
}
return 0;
}