P9525 [JOISC 2022] 团队竞技 题解

Description

JOI 大学有 NN 只海狸,他们都参与竞技编程。每只海狸有三项能力值:思考值,行动值和运气值。如果一个能力值很大,意味着他这项能力比较强大。对于第 i (i[1,N])i~(i\in[1,N]) 只海狸,他的思考值为 XiX_i,行动值为 YiY_i,运气值为 ZiZ_i

今年 JOI 大学的海狸们将参与一场团体竞技编程,一支队伍由三名队员组成。Bitaro 是 JOI 大学的教练,由于团队合作很重要,Bitaro 决定从 NN 只海狸中选出三只海狸组成队伍,这三只海狸要满足以下条件:

条件:每个成员都有自己的优势,这意味着每个成员都有一项能力值严格大于其他两人的对应能力值。

在所有符合条件的组队中,Bitaro 想要选一个总能力最强的队伍,一个队伍的总能力定义为:三人最大思考值,三人最大行动值和三人最大运气值之和。

请你求出,是否存在一个符合条件的组队,如果是,计算队伍总能力可能的最大值。

3N1500003\leq N\leq 1500001Xi,Yi,Zi1081\leq X_i,Y_i,Z_i\leq 10^8

Solution

首先先把 x,y,zx,y,z 三维分别最大的拿出来,假设 xx 最大的是 kk

那么如果 yky_k 或者 zkz_k 仍然是最大的,kk 怎么选都会不合法,就把 kk 删掉。对 yyzz 最大的做同样的事情。

这么删到最后一定满足 x,y,zx,y,z 最大的位置互不相同,这三个显然就是答案。

如果只剩下不超过 22 个则无解。

时间复杂度:O(nlogn)O(n\log n)

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <bits/stdc++.h>

// #define int int64_t

const int kMaxN = 1.5e5 + 5;

int n;
int a[kMaxN], b[kMaxN], c[kMaxN];
std::set<std::pair<int, int>> sa, sb, sc;

void del(int x) {
sa.erase({a[x], x}), sb.erase({b[x], x}), sc.erase({c[x], x});
}

void dickdreamer() {
std::cin >> n;
for (int i = 1; i <= n; ++i) {
std::cin >> a[i] >> b[i] >> c[i];
sa.emplace(a[i], i);
sb.emplace(b[i], i);
sc.emplace(c[i], i);
}
for (; sa.size() >= 3;) {
int x = sa.rbegin()->second, y = sb.rbegin()->second, z = sc.rbegin()->second;
bool fl = 1;
if (b[x] == b[y] || c[x] == c[z]) del(x), fl = 0;
if (a[y] == a[x] || c[y] == c[z]) del(y), fl = 0;
if (a[z] == a[x] || b[z] == b[y]) del(z), fl = 0;
if (fl) return void(std::cout << a[x] + b[y] + c[z] << '\n');
}
std::cout << "-1\n";
}

int32_t main() {
#ifdef ORZXKR
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);
int T = 1;
// std::cin >> T;
while (T--) dickdreamer();
// std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
return 0;
}

P9525 [JOISC 2022] 团队竞技 题解
https://sobaliuziao.github.io/2025/03/30/post/999229d2.html
作者
Egg_laying_master
发布于
2025年3月30日
许可协议