不一定所有人都被选上
遍历所有的左子数组,然后对右子数组二分查找邻近值。
遍历所有的左子数组,然后对右子数组二分查找邻近值。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
multiset<ll> s;
int main()
{
int n;
cin>>n;
int a[n+1];
ll sum[n+1] = {0};
for(int i = 1;i<=n;i++)
{
cin>>a[i];
sum[i] = sum[i-1] + a[i]; //构造前缀和
}
for(int i = 1;i<=n;i++)
{
for(int j = i;j<=n;j++)
{
s.insert(sum[j] - sum[i-1]); //将所有的区间和存起来
}
}
ll res = LLONG_MAX;
for(int i = 1;i<n;i++) //遍历左子数组的右端点
{
for(int j = i;j<=n;j++) //删除所有与右子数组相交的区间
{
s.erase(s.find(sum[j] - sum[i-1]));
}
for(int j = 1;j<=i;j++). //遍历左子数组的左端点,根据左右端点得出左子数组的和,再二分查找最近的右子数组
{
ll target = sum[i] - sum[j-1];
auto it = s.lower_bound(target);
if(it != s.end()) //第一个>=target的数
res = min(res, abs(target - *it));
if(--it != s.begin()) //最后一个<target的数,因为是绝对值要考虑大于和小于
res = min(res,abs(target - *it));
}
}
cout<<res;
}
2 回复
0 转发
0 喜欢
5 阅读



