问题 G: 走方格 upc个人训练第9场

题目描述

给你一条直线上的n个方格,每个方格踩下去有一个权值,小A踩方格的路线为1-3-5-7-9....小B踩方格的路线为2-4-6-8-10,现在你可以提前去掉一个方格,小A踩方格的路线仍为1-3-5-7-9....小B踩方格的路线仍为2-4-6-8-10,现在问有多少种去掉方格的方案使得小A和小B获得的权值和相同。

输入

第一行一个正整数n。
第二行n个数表示从前到后每个方格的权值。
n<=200000,0<=权值<=10000。

输出

一个数表示方案数。

样例输入 

7
5 5 4 5 5 5 6

样例输出 

2

提示

对于8%的数据,n<=10;
对于40%的数据,n<=2000;
对于100%的数据,n<=200000;

 解析:

巧妙利用前缀和,完成离线单点修改嘿嘿。

记录的是奇数前缀和和偶数前缀和,第一个奇数,第二个这样。。。

最后判断条件的时候不要忘了左边的奇数或偶数和要减掉当前数(如果需要的话),但是右边的不要减掉,因为已经是到当前数的前缀和了,最后暴力枚举可以了。。。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=200000+10;
int n,a[maxn],s1[maxn],s2[maxn],sum1,sum2;
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=n;i++)
	{
		if(i&1)
		{
			s1[(i+1)/2]+=(a[i]+s1[(i+1)/2-1]);
			sum1+=a[i];
		}
		else if(i%2==0)
		{
			s2[i/2]+=(a[i]+s2[i/2-1]);
			sum2+=a[i];
		}
	}
	int cnt=0;
	for(int i=1;i<=n;i++)
	{
		int x=s1[(i+1)/2]; //左边奇数和 
		int y=s2[(i)/2];  // 左边偶数和 
		int t1=x;
		int t2=y;
		if(i&1)
			x-=a[i];
		else
			y-=a[i];
		if(x+sum2-t2==y+sum1-t1)
			cnt++;
	}
	printf 
	return 0;
}
发布了51 篇原创文章 · 获赞 21 · 访问量 3089

猜你喜欢

转载自blog.csdn.net/qq_44115065/article/details/102711491