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;
}
posted @ 2023-02-20 18:44  Cheng_Mao  阅读(20)  评论(0编辑  收藏  举报