天梯赛的赛场(STL)

168 阅读2分钟

L2-046 天梯赛的赛场安排 (pintia.cn)

原文题面

image.png

原文描述

天梯赛每个赛场最多容纳 cc 名队员, 每个赛场的队员可以来自不同学校,每个学校都需要为这个赛场的本校队员配备一名本校的监考老师。

现在按学校剩余未安排考场的考生人数降序进行安排考场,按考场安排的先后为考场进行编号,如题面所给方式对每个学校的考生进行安排。

输入样例

10 30
zju 30
hdu 93
pku 39
hbu 42
sjtu 21
abdu 10
xjtu 36
nnu 15
hnu 168
hsnu 20

输出样例

zju 1
hdu 4
pku 2
hbu 2
sjtu 1
abdu 1
xjtu 2
nnu 1
hnu 6
hsnu 1
16

题目分析

本题主要考察 阅读理解 STL 中的 priority_queue 的考察。

priotiy_queue 意为优先队列,相对于普通队列的先进先出,在优先队列中,元素具有优先级,每次 pop() 操作都会将队列中优先级最高的元素删去。其数据结构通过堆实现,结构上可以用完全二叉树来表示。

priority_queue<Type, Container, Functional> 为优先队列的一般定义。

Type 为数据类型,Container 为容器类型,默认为 vector<>Functional 为比较方式,为 greater<> (大根堆) 和 less<> (小根堆)。

对于本题,我们定义 pair<string, int> 为每个学校的名称及其剩余未安排人数,将其储存到优先队列中,然后便可以进行题目所述的模拟过程。

对于操作二中的按编号大小寻找考场,由于本题数据较小,可以以每次 O(n)O(n) 的方式新开一个数组实现具体操作。

Accept代码

#include <bits/stdc++.h>

using namespace std;

const int N = 5010;

int n, c;
int cnt;
priority_queue<pair<int, string>> q;
int m = -1, st[N];

int main()
{
    cin >> n >> c;
    for (int i = 0; i < n; i ++)
    {
        string s;
        int x;
        cin >> s >> x;
        cout << s << ' ' << (x + c - 1) / c << "\n";
        q.push({x, s});
    }
    while (!q.empty())
    {
        auto [x, s] = q.top(); q.pop();
        if (x >= c)
        {
            x -= c;
            cnt ++;
            if (x) q.push({x, s});
        }
        else
        {
            int u = 0;
            while (u <= m)
            {
                if (st[u] >= x)
                {
                    st[u] -= x;
                    break;
                }
                u ++;
            }
            if (u > m) st[++ m] = c - x, cnt ++;
        }
    }
    cout << cnt;
    return 0;
}