欢乐赛B

CF1118B
原题链接https://vjudge.net/contest/350953#problem/B
在这里插入图片描述
在这里插入图片描述
题意大概是,有N块糖果重量不同,拿出其中一块,剩下的糖果中奇数和偶数的总重量相同,在这里使用计算奇偶前缀和的方法:即前N个数中有多少奇数位的总和和偶数位的总和。
前缀和:
对于1 2 3 4 5 6
假如我们要计算3 4的和
我们可以先计算出1 2 的和以及1 2 3 4 的和
3 4 显然等于(1 2 3 4)-(1 2);
我们用a[n]来记录前n项的和如果计算3 4 显然是a[4]-a[2];
由此可知计算x,y的值就是a[y]-a[x-1];

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<queue>
using namespace std;
long long a[300005];
long long odd[300005];
long long even[300005];
int main()
{
	long long n;
	long long i;
	scanf("%lld",&n);
	for(i=1; i<=n; i++)
	{
		scanf("%lld",&a[i]);
	}
	odd[1]=a[1];//第一个奇数是1,所以要加上第一天的数
	even[1]=0;//第一个偶数为0;第零天显然为0
	for(i=2; i<=n; i++)//计算第二天到N天
	{
		if(i%2==1)//假如是奇数,就要加上当前的数,由于没有新加入的偶数,偶数和不变。PS:假如是3的话 我们就要算 奇数1和3的值,偶数的话由于新的一位不是偶数所以还是2的时候计算的0和2的值不变。
		{
			odd[i]=a[i]+odd[i-1];//odd[i-1]记录的是前i-1项中奇数的和,把新出现的奇数加上即可
			even[i]=even[i-1];
		}
		else//同奇数;
		{
			odd[i]=odd[i-1];
			even[i]=even[i-1]+a[i];
		}
	}
	long long ans=0;//记录答案数
//PS:
//对于 1 2 3 4 5 6
//假如我们拿出第三天的数,奇数和就变成1,2的奇数和以及4 5 6的偶数和(因为3拿走了所以4 5 6会往前进一位奇变偶,偶变奇);偶数和就是1 2 的偶数和加上4 5 6的奇数和,理由同上。
	for(i=1; i<=n; i++)//遍历其中每一位就好
	{
		if(odd[i-1]+even[n]-even[i]==even[i-1]+odd[n]-odd[i])//使用前缀和的方法来计算后面的奇偶的和。i的位数是我们去掉的不计算,此时计算的是i+1到n所以为n-i;
		{
			ans++;
		}
	}
	printf("%lld",ans);
	return 0;
}
发布了130 篇原创文章 · 获赞 3 · 访问量 1605

猜你喜欢

转载自blog.csdn.net/yeyuluo/article/details/103950779
今日推荐