思想
我刚开始是这样想的,通过两层循环i,j控制终点位置,对[l,r]区间进行求和,同时再通过一层循环k枚举[l,r]区间每个数,我们控制某个数a[k]不被累加到SUM里.最后我们看一下SUM和这个没被加入到SUM里的a[k]是否相等,如果相等,那么cnt++.
这个算法是暴力做法,时间复杂度1e9,超时
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e3 + 10;
int a[N];
//unordered_set<int>haxi;
map<int, int>haxi;
int cnt, sum, n;
signed main()
{
cin.tie(nullptr)->sync_with_stdio(false);
cin >> n;
for (int i = 1; i <= n; i++)cin >> a[i];
for (int i = 1; i <= n; i++) //终点
{
sum = 0;
for (int j = 1; j <= i; j++) //标记哪个不加
{
for (int k = 1; k <= i; k++) //累加区间和
{
if (k != j)
{
sum += a[k];
}haxi[a[k]]++;
}
if (haxi.count(sum))
{
cnt++;
}
}
}
cout << cnt << endl;
return 0;
}
优解
像这种题暴力做不了的就要先去观察,找规律.
通过观察我们发现,当满足题目要求时,序列中一定有 最大值=sum/2这个条件成立.
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
const int N=2e5+10;
int a[N],sum,cnt,ans=-0x3f3f3f3f;
signed main()
{
cin.tie(nullptr)->sync_with_stdio(false);
cin>>n;
for(int i=0;i<n;i++)cin>>a[i];
for(int i=0;i<n;i++)
{
sum+=a[i];
ans=max(a[i],ans);
if(ans*2==sum)cnt++;
}
cout<<cnt<<endl;
return 0;
}