题目描述:
题目大意:拿的想要使得上述表达式最小,分配的想要这个最小值最可能大。问拿的人最大可以使表达式为多少。
思想:贪心&排序
先把数组排序,分为连续的三段,要是得这个差值尽可能的大,可以把最小的一段或者最大的那一段放在第二堆里面。即可能摆法如下:
第一堆(中间的一段) 第二堆(最小的一段) 第三堆(最大的一段)
假如我们在第二堆放最小的那个石头,第一堆放最大的那个石头,那么我们就已经得到了 max - min 的一个权值,在另一堆里面,我们能得到第二个极小值 - 最小值的贡献。
最中间那堆石头肯定是数组中最小的一段或者是最大的一段。如果中间那堆石头是最小的那一段,那么第一堆肯定是最大的那个数(仅有一个),其余放在第三堆里面。
最后枚举第二堆的到达位置即可。
AC代码:
#include <numeric>
#include <string>
#define ll long long
#include<set>
#include<bitset>
#include<iostream>
#include<map>
#include<queue>
void solve() {
int n; cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++)
cin >> a[i];
sort(a.begin(), a.end());
// 把 a 分成连续的三段
int ans = 0;
// 1 3 5 6 8 10 19 20
for (int i = 0; i < n - 1; i++)
ans = max(ans, a[i + 1] - a[i] + a[n - 1] - a[i]);
for (int i = n - 1; i >= 2; i--)
ans = max(ans, a[i] - a[i - 1] + a[i] - a[0]);
cout<< ans << endl;
}
int main(){
int t;
cin >> t;
while (t--) {
solve();
}
}