洛谷B4038 [GESP202409 三级] 平衡序列 题解

原题传送门

前言

当我以一种十分激动的心情参加了GESP的2024-9的三级考试时。
打开了此题,然后……自以为是的拿着暴力一顿乱写!然后TLE
直到结束我还是没有想出来! (太菜了!!!)
以一种十分沮丧的心情走出了考场……
于是写了这篇题解…… (讲了这么多,还是太菜了!)

题目解析

  1. 需要输入一个长度为 \(n\) 的正整数序列 \(a\)
  2. 找到一个 \(i\)\(1 \leq i < n\)) 使得a[1]+a[2]+a[3]+…+a[i]==a[i+1]+a[i+2]+a[i+3]+…+a[n]
  3. 本题单个测试点内包含多组测试数据! 所以,可能要用memset()了。

解题思路

1、暴力!

我在考场就是这个方法!这里就不展开了。因为会 TLE

2、使用前缀和

前置知识

前缀和,顾名思义,指的是数组内存储的时当前元素与之前的所有元素的和。(很好理解对吧!?)
举个栗子!

点击查看实例代码
int n;
int a[20];
// 创建前缀和数组b
int b[20];
cin>>n;
for(int i=1;i<=n;i++){
	cin>>a[i];
}
// for循环求出前缀和
for(int i=1;i<=n;i++){
	b[i]=a[i]+b[i-1];
}
// 输出
for(int i=1;i<=n;i++){
	cout<<b[i];
}

// 输入:
3
1 3 5
//输出:
1 4 9

好了,懂了前缀和,你就懂了这道题的做法!

真正的解题思路

现在,摆在面前的唯一难题便是如何快速求出 a[1]+a[2]+a[3]+…+a[i]a[i+1]+a[i+2]+a[i+3]+…+a[n]
第一个很好求,在得到前缀和数组 \(b\)b[i]里的内容便是第一个。
第二个,则需思考一下!其中b[n]里的内容可以被拆分为b[i]+a[i+1]+a[i+2]+a[i+3]+…+a[n]
所以!第二个就可以用b[n]-b[i]!
然后,与一些基本的输入输出结合,你得到了此题的完整代码!

CODE

点击查看完整代码
#include<bits/stdc++.h>
using namespace std;
int t;
int n;
int a[10005];
int b[10005];
int main(){
	cin>>t;
	while(t--){
		cin>>n;
		for(int i=1;i<=n;i++){
			cin>>a[i];
		}
		for(int i=1;i<=n;i++){
			b[i]=a[i]+b[i-1];
		}
		bool flag=true;
		for(int i=1;i<=n;i++){
			if(b[i]==b[n]-b[i]){
				cout<<"Yes"<<endl;
				flag=false;
				break;
			}
		}
		if(flag){
			cout<<"No"<<endl;
		}
	}
	return 0;
}

完结撒花!!

posted @ 2025-02-17 22:17  Zpy_101001  阅读(287)  评论(1)    收藏  举报