题目来自于AcWing平台:https://www.acwing.com/problem/content/description/4968/。
以blog的形式记录程序设计算法学习的过程,仅做学习记录之用。
思路参考自题解:https://www.acwing.com/solution/content/221015/。
最关键的思路在于,胜出的条件是 X > Y + Z X\gt{Y+Z} X>Y+Z,这个不等式可以等价变换为 X ? Y ? Z > 0 X-Y-Z\gt0 X?Y?Z>0,因此这道题目便豁然开朗了。对于 A , B , C A, B, C A,B,C | B , A , C B, A, C B,A,C | C , A , B C, A, B C,A,B三种排列顺序,分别求出每种情况下的 X ? Y ? Z X-Y-Z X?Y?Z,然后对保存着 X ? Y ? Z X-Y-Z X?Y?Z信息的数组进行降序排序。
显然,如果 ( X ? Y ? Z ) [ i ] (X-Y-Z)[i] (X?Y?Z)[i]如果大于0,则说明这个选择满足题意,可以将它统计进加和 s u m sum sum中,而如果它小于0,则 s u m sum sum也相应减小,如果最后 s u m ≤ 0 sum\leq0 sum≤0,则说明此时的枚举该停止了。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 5;
int n;
LL res = 0;
void check(vector<int> a, vector<int> b, vector<int> c){
for(int i = 0; i < n; i ++){
a[i] -= b[i] + c[i];
}
sort(a.begin(), a.end());
LL cnt = 0, sum = 0;
for(int i = a.size()-1; i >= 0; i --){
sum += a[i];
if(sum <= 0) break;
cnt ++;
}
if(cnt != 0) res = max(res, cnt);
}
int main()
{
cin >> n;
vector<int> a(n), b(n), c(n);
for(int i = 0; i < n; i ++) cin >> a[i];
for(int i = 0; i < n; i ++) cin >> b[i];
for(int i = 0; i < n; i ++) cin >> c[i];
check(a, b, c);
check(b, a, c);
check(c, a, b);
if(res == 0) cout << "-1";
else cout << res;
return 0;
}