截断数组(前缀和)

给定一个长度为 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;
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值