题目分析
优化的暴力枚举,考虑枚举左区间并且二分查找一下和右区间差值小的结果,用一个多重集合保存一下左区间的和
时间复杂度 $O(n^2logn)$
#include <iostream>
#include <cmath>
#include <algorithm>
#include <set>
using namespace std;
typedef long long LL;
const int N = 1001;
int a[N];
int main()
{
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", a + i);
LL ans = abs(a[1] - a[2]);
// l1, r1, l2 ,r2
multiset<LL> st; //存储左区间左右端点在 [1 —— l2-1]的和
for(int l2 = 2, l1 = 1; l2 <= n && l1 <= n; l2++, l1++) {
LL sum2 = 0;
for(int r2 = l2; r2 <= n; r2++) {
sum2 += a[r2];
//set中二分找左区间[l1——r1]第一个距离sum最近的答案
auto it = st.lower_bound(sum2);
// 在合法区间内部
if(it != st.end() && it != st.begin()) ans = min({ans, abs(sum2 - *it), abs(sum2 - *(--it))});
}
//维护左区间[l1——r1]的区间和
LL sum1 = 0;
for(int r1 = l1; r1 <= n; r1++) {
sum1 += a[r1];
st.insert(sum1);
}
}
printf("%lld\n", ans);
return 0;
}