codeforces 466c(暴力枚举)

题目链接

思路如下

*题意: 给定一个序列,问有多少种方案可以将此序列分割成3个序列元素和完全相同的子序列。(子序列不能为空)。即问有多少个点对(i,j)满足a[1]+…+a[i-1]=a[i]+a[i+1]+…+a[j]=a[j+1]+a[j+2]+…+a[n]

  • 思路:这一题直接暴力求解就行了
    1. 看 n是否小于3 或者 数列元素之和 不能被3整除,如果是直接输出 0
    2. 当我们考虑某个位置 J 的时候,如果该位置的前缀和 sum[ J ] 是序列前缀和sum[ n ]的三分之二(此时剩下的区间的和一定是1/3sum[n]),那么这个点方案数ans为:在 J 下标位置之前的位置(假设为 i ) 出现过 sum[ i ] == 1/3 * sum[ n ] 的次数假设为ans1…最终把所有出现 sum[ J ] == 1/3 * sum[n] 的位置的方案数全部加起来,就是我们想要的答案。。
      ⚠️:sum[] ,ans 的数据类型必须是 long long 。。

题解如下

#include
using namespace std;

const int Len = 5e5 + 5;
int ar[Len];
long long sum[Len];

int main()
{
    int n;
    scanf("%d",&n);
    for(int i = 1; i <= n; i ++)
        scanf("%d",&ar[i]),sum[i] += sum[i - 1] + ar[i];

    if(n < 3 || sum[n] % 3 != 0)
    {
        cout<<0;
        return 0;
    }
    long long int ans = 0,ans1 = 0;
    for(int i = 1; i < n; i ++)
    {
        if(sum[i] == sum[n] / 3 * 2)
            ans += ans1;
        if(sum[i] == sum[n] / 3)
            ans1 ++;
    }
    cout<<ans;

    return 0;
}

你可能感兴趣的:(Codeforces)