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

· · 题解

闲话

简单模拟,我觉得真没有黄。

思路

考虑每个操作。

对于四个属性,可以使用结构体 struct 绑定四个属性。

然后题目中有排序要求,具体可以分为以下两类:

  1. 按成绩从大到小排序。
  2. 按编号从小到大排序。

可见,这两个简单排序我们直接使用 sort 即可,构建两个 cmp 函数即可。

考虑 A 队放入操作,先按成绩排序,因为 A 队有同一元素的人不超过 4 个,我们用两个 cnt 来表示元素 1,0 的人在 A 队的出现次数,如果满足有一个是 4 人,就暴力遍历到第一个相反元素。注意因为我们是找到第 i 个人判断的,所以第 i 个人不能忽略,要从 i 开始遍历。

对于 B 队,已经进入 A 队的我们肯定不考虑,这一部分我用的 bitset 实现的。工会很明显我们还可以开一个像 cnt 的桶,在插入 A 队时也记录即可。

最后我们放入 A,B 队直接用数组即可。

因为我们要对于每个人重新记录一遍 A,B 队,所以注意清空,因为我比较懒,所以放入 A,B 队的数组用的 vector,存储工会的桶用的 map

其他就没了吧,感觉思路很显然,没有黄。

:::success[std]

#include<bits/stdc++.h>
using namespace std;
constexpr int N = 120;
struct player{
    int sex, score, id, name;
    //分别对应 元素 成绩 工会 序号
}s[N];
int n, cnt[2];
bool cmp(player a, player b){return a.name < b.name;}//按序号
bool cmp1(player a, player b){return a.score > b.score;}//按成绩
vector<player> A, B;
bitset<N> b;
map<int, int> mp;
int main()
{
    ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);
    cin >> n;
    for(int k = 1;k <= n;k ++)
    {
        s[k].name = k, cin >> s[k].sex >> s[k].id >> s[k].score;
        A.clear(), B.clear();mp.clear();cnt[1] = cnt[0] = 0;b.reset();//清空
        sort(s + 1, s + 1 + k, cmp1);
        for(int i = 1;i <= k;i ++)
        {
            if(A.size() == 5) break;
            if(cnt[0] != 4 && cnt[1] != 4) A.push_back(s[i]), cnt[s[i].sex] ++;
            else
            {
                if(cnt[1] == 4) {for(int j = i;j <= k;j ++) if(s[i].sex == 0) {A.push_back(s[j]);break;}}
                    else {for(int j = i;j <= k;j ++) if(s[i].sex == 1) {A.push_back(s[j]);break;}}
            }
        }
        for(auto p : A) b.set(p.name), mp[p.id] ++;//把已经用过的标记
        for(int i = 1;i <= k;i ++)
        {
            if(B.size() == 12) break;
            if(b[s[i].name]) continue;
            if(mp[s[i].id] < 5) B.push_back(s[i]), mp[s[i].id] ++, b.set(s[i].name);
        }
        sort(A.begin(), A.end(), cmp);sort(B.begin(), B.end(), cmp);
        for(auto p : A) cout << p.name << ' ';
        for(auto p : B) cout << p.name << ' ';
        cout << '\n';
    }
    return 0;
}

:::