洛谷B4038 [GESP202409 三级] 平衡序列 题解
前言
当我以一种十分激动的心情参加了GESP的2024-9的三级考试时。
打开了此题,然后……自以为是的拿着暴力一顿乱写!然后TLE。
直到结束我还是没有想出来! (太菜了!!!)
以一种十分沮丧的心情走出了考场……
于是写了这篇题解…… (讲了这么多,还是太菜了!)
题目解析
- 需要输入一个长度为 \(n\) 的正整数序列 \(a\) 。
- 找到一个 \(i\) (\(1 \leq i < n\)) 使得
a[1]+a[2]+a[3]+…+a[i]==a[i+1]+a[i+2]+a[i+3]+…+a[n]
- 本题单个测试点内包含多组测试数据! 所以,可能要用
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;
}
完结撒花!!