AtCoder Beginner Contest 102 D - Equal Cut 题解
题意
AtCoder Beginner Contest 102 D - Equal Cut
给定一个数组,切3刀把他分成4份。要求求出4份子数组中的最大的数组和-最小的数组和的值最小。
思路
我们可以枚举第二刀,这样就把整个数组分为了 \(L,R\) 两个部分。
如果想要让整体最小,那么第一刀一定尽量让 \(|L_1-L_2|\) 变得更小,也就是两个更加接近。这个过程我们可以用双指针来实现。第三刀的切法同理。每次枚举第二刀的时候,都求一下当前的结果就好。
代码
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <cmath>
#define fi first
#define se second
using namespace std;
using ll = long long;
using pii = pair<int, int>;
const double eps = 1e-4;
const int N = 2e5+10;
ll n, a[N], b[N], res = 1e18;
void update_res() {
ll minv = 1e18, maxv = 0;
for(int i=1; i<=4; i++) {
ll t = a[b[i]] - a[b[i-1]];
minv = min(minv, t);
maxv = max(maxv, t);
}
res = min(res, maxv-minv);
}
void solve() {
scanf("%lld", &n);
for(int i=1; i<=n; i++) {
scanf("%lld", &a[i]);
a[i] += a[i-1];
}
// b[1..3]表示第1-3刀
for(b[1] = 1, b[2] = 2, b[3] = 3, b[4] = n; b[2] <= n-2; b[2]++) {
// 求第一刀 当下一个位置比当前的位置|L1-L2|更小时就++
while(abs(a[b[1]] - (a[b[2]]-a[b[1]])) > abs(a[b[1]+1] - (a[b[2]] - a[b[1]+1]))) b[1]++;
// 求第二刀
while(abs((a[b[3]]-a[b[2]]) - (a[b[4]]-a[b[3]])) > abs((a[b[3]+1]-a[b[2]]) - (a[b[4]]-a[b[3]+1]))) b[3]++;
update_res();
}
printf("%lld\n", res);
}
int main() {
// multiple case
// int t; scanf("%d", &t);
// while(t--) {
// solve();
// }
// single case
solve();
return 0;
}
不忘初心方得始终