acwing 截断数组
题目给定一个长度为 n 的数组 a_1,a_2,…,a_n。
现在,要将该数组从中间截断,得到三个非空子数组。
要求,三个子数组内各元素之和都相等。
请问,共有多少种不同的截断方法?
输入格式
第一行包含整数 n。
第二行包含 n 个整数 a_1,a_2,…,a_n。
输出格式
输出一个整数,表示截断方法数量。
数据范围
前六个测试点满足 1≤n≤10
所有测试点满足 1≤n≤10^5,−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
题解
分析
- s数组为前缀和数组,这里边录入边转换
- 和能平均分为三份,意思是每一段的和都是s[n]/3
- 先判断一下是否能被整除,分成三段,不能直接输出0,否则进行操作
- 使用一层for循环进行遍历 ,用来找到两个切入点,等于一倍平均值为第一个点
等于二倍平均值为第二个点,之所以ans+=count,是因为比如前面有3个点可以切第一刀,那么后面找到第二刀时,就有三种可能性,所以要加上3
代码
#include "iostream"
#define ll long long
const int N = 100010;
int s[N]={0};
using namespace std;
int main(){
ll n,ans=0;
cin>>n;
for(int i=1;i<=n;i++){
cin>>s[i];
s[i]+=s[i-1];
}
if(s[n]%3)cout<<0;
else{
ll ave = s[n] / 3;
ll count = 0;
for(int i=1;i<n;i++){
if(s[i]==ave*2)ans+=count;
if(s[i]==ave)count++;
}
cout<<ans;
}
return 0;
}