题解:P16441 [XJTUPC 2026] 直播获奖

· · 题解

模拟,按照题意模拟即可。

我非常喜欢 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 的数组,sSS 跟着输入存玩家,sS 的副本,用于每次进行选拔。

清空存 $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; } ```