题解:P16441 [XJTUPC 2026] 直播获奖
Easy_du
·
·
题解
大模拟,按照题意模拟即可。
我非常喜欢 vector,所以接下来的数组我都使用了 vector。
题目思路
因为 1 \le n \le 100,所以不用考虑进行大量优化。
读题后,显然,一个玩家有多个信息,所以使用结构体存储。
struct Players {
int uid; //uid
int y; //阴阳
int guild; //公会
int score; //成绩
bool operator < (const Players &a) const {
return score > a.score;
}
};
接着,建变量,我们需要特殊考虑 S 的存储,因为每次的 S 在选拔时都会删除一些玩家信息,所以建两个存 S 的数组,s 和 S,S 跟着输入存玩家,s 当 S 的副本,用于每次进行选拔。
清空存 $A$ 队的数组。
先判断 $|s| \le 4$,如果 $|s| \le 4$,那么 $A = s$,将 $s$ 清空,因为 $s$ 中的玩家进入了 $A$ 队。
否则,将 $s$ 进行排序,接着建一个数组 $t$,让 $s$ 的前五个元素加入 $t$,即 `t.insert(t.begin(), s.begin(), s.begin() + 5);`。
建两个变量 $yin, yang$,遍历 $t$,如果有元素的 $y = 0$,那么 $yin = 1$,如果有元素的 $y = 1$,那么 $yang = 1$,遍历结束后,如果 $yin = 1$ 且 $yang = 1$,那么 $A = t$,且 `s.erase(s.begin(), s.begin() + 5);`,同样,因为 $s$ 中的玩家进入了 $A$ 队。
否则,设一个变量 $y$ 表示 $t$ 中的玩家都是阴 / 阳,将 $s$ 中的所有玩家进行遍历,接着将这些玩家按照阴阳分类,将与 $y$ 阴阳相同的取前 $4$ 名玩家,如果不足 $4$ 名,那么取所有这几名玩家,再取与 $y$ 阴阳不同的成绩最高的一名玩家(如果有),加入 $A$ 队。
接着,用一个哈希表记录 $A$ 队的玩家 uid,再建立一个 $p$ 数组,遍历 $s$,如果这个玩家不在 $A$ 中(用前面的哈希表判断),那么加入 $p$,遍历结束后 $s = p$ 即可。
---
$B$ 队的选拔:
清空存 $B$ 队的数组。
维护一个数组 $sum$,记录每个公会进入 $A$ 队和 $B$ 队的人数。
遍历 $s$,如果已经 $B$ 队够 $12$ 人,那么退出遍历,否则判断现在遍历的第 $i$ 个玩家所在的公会 $i.guild$ 进入 $A$ 队和 $B$ 队的人数,即 $sum_{i.guild}$,是否 $ < 5$,如果 $ < 5$,那么 $sum_{i.guild} + 1$,将这个玩家加入 $B$ 队。
## AC Code
```cpp line-numbers
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <climits>
#include <iomanip>
#include <vector>
#include <string>
#include <cmath>
#include <queue>
#include <deque>
#include <set>
#include <map>
#define ios ios::sync_with_stdio(false), cin.tie(nullptr)
#define double long double
#define int long long
#define endl '\n'
#define all(x) x.begin(), x.end()
using namespace std;
struct Players {
int uid; //uid
int y; //阴阳
int guild; //公会
int score; //成绩
bool operator < (const Players &a) const {
return score > a.score;
}
};
int n;
vector<Players> s, S;
vector<Players> a;
vector<Players> b;
vector<int> sum(105);
inline void A_selection() {
a.clear();
sort(all(s));
if (s.size() <= 4) {
a = s;
s.clear();
return;
}
vector<Players> t;
t.insert(t.begin(), s.begin(), s.begin() + 5);
bool yin = false, yang = false;
for (auto i : t) {
if (i.y)
yang = true;
else
yin = true;
}
if (yang && yin) {
a = t;
s.erase(s.begin(), s.begin() + 5);
return;
}
int y = (yin ? 0 : 1);
vector<Players> ax, ay;
for (auto i : s)
if (i.y == y)
ax.push_back(i);
else
ay.push_back(i);
for (int i = 0; i < min(4LL, (int)ax.size()); i++)
a.push_back(ax[i]);
if (!ay.empty())
a.push_back(ay[0]);
unordered_map<int, bool> uid_xia;
for (auto i : a)
uid_xia[i.uid] = true;
vector<Players> p;
for (auto i : s)
if (!uid_xia[i.uid]) p.push_back(i);
s = p;
}
inline void B_selection() {
b.clear();
for (auto j : a)
sum[j.guild]++;
for (auto i : s) {
if (b.size() >= 12)
return;
if (sum[i.guild] < 5) {
sum[i.guild]++;
b.push_back(i);
}
}
}
signed main() {
cin >> n;
for (int i = 1, x, y, z; i <= n; i++) {
sum.assign(105, 0);
cin >> x >> y >> z;
S.push_back({i, x, y, z});
s = S;
A_selection();
B_selection();
sort(a.begin(), a.end(), [](Players a, Players b) {
return a.uid < b.uid;
});
sort(b.begin(), b.end(), [](Players a, Players b) {
return a.uid < b.uid;
});
for (auto Player : a)
cout << Player.uid << ' ';
for (auto Player : b)
cout << Player.uid << ' ';
cout << '\n';
}
return 0;
}
```