CodeForces 21C 题解
题解笔记
CF21C Stripe 2(Stripe.cpp)
时间限制 \(1s\) | 内存限制 \(64M\)
题目描述:
给出一个长度为 \(n\) 的序列,问有多少种方案将序列划分为恰好连续的三段(每个元素都属于某一段),使得每一段的和都相等。
输入格式:
第一行仅有一个整数 \(n\) ( \(1 \leq n \leq 105\) ),第二行包含 n 个整数 \(a_1,a_2,...,a_n\) ( \(\mid a_i \mid \leq 104\))。
输出格式:
仅有一行包含一个整数,表示方案数。
输入输出样例:
样例1输入 | 样例1输出 | 样例2输入 | 样例2输出 |
---|---|---|---|
4 1 2 3 3 |
1 | 5 1 2 3 4 5 |
0 |
解题思路:
既然是求和,就考虑到了前缀和,统计前缀和。扫一遍前缀和数组,如果某一个前缀和等于了总和的 \(\dfrac{1}{3}\) ,统计变量cnt++
;如果某一个前缀和等于了总和的 \(\dfrac{2}{3}\),那只需要检查前面有多少个 \(\dfrac{1}{3}\) ,将 ans+=cnt
就好了。
参考代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=1e5+5;
typedef long long ll;
ll pre[MAXN];
ll ans,cnt;
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",pre+i);
pre[i]+=pre[i-1];
}
if(pre[n]%3)
{
printf("0");
return 0;
}
ll wz=pre[n]/3;
for(int i=1;i<n;i++)
{
if(pre[i]==wz<<1) ans+=cnt;
if(pre[i]==wz) cnt++;
}
printf("%lld",ans);
return 0;
}