给定一个长度为 nn 的数组 a1,a2,…,an 。
现在,要将该数组从中间截断,得到三个非空子数组。
要求,三个子数组内各元素之和都相等。
请问,共有多少种不同的截断方法?
输入格式
第一行包含整数 nn。
第二行包含 nn 个整数 a1,a2,…,ana1,a2,…,an。
输出格式
输出一个整数,表示截断方法数量。
数据范围
前六个测试点满足 1≤n≤10 1≤n≤10。
所有测试点满足 1≤n≤1e5 , −10000≤ai≤10000。
输入样例1:
4
1 2 3 3
输出样例1:
1
输入样例2:
5
1 2 3 4 5
输出样例2:
0
输入样例3:
2
0 0
输出样例3:
0
基本原理:要将数组拆成三份 , 就说明一定有两个间断点 . 两个截断点之间一定有一个数,也就是说第三部分的开头为 i 的话,则第一部分末尾至少是 i - 2 ,第二部分末尾则为i - 1。循环中先找第一个间断点,然后找第二个间断点。每找到一个第二个间断点,res就加一次已找到 第一间断点的和。最后res即为答案。
//res代表答案,sum代表第一间断点的数量。
#include<iostream>
#include<iostream>
using namespace std;
const int N = 100010;
typedef long long LL;
int n;
int a[N];
LL s[N];
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
s[i] = a[i] + s[i - 1];
}
LL a = s[n] / 3;
LL sum = 0, res = 0;
if (s[n] % 3 != 0 || n < 3)cout << 0 << endl;
//如果数组总和不是3的倍数或数组小于三位,就一定不成立
else
{
for (int i = 3; i <= n; i++)
{
if (s[i - 2] == a)sum++; //计算第一间断点
if (s[n] - s[i - 1] == a)res += sum; //说明找到一个第二间断点,+=已找到所有间断点
}
cout << res << endl;
}
return 0;
}