思路

  • 模拟整个过程
  • 用优先队列保证,每次处理的是人数最少的学校
  • 注意一个点,当第二种情况发生的时候,此时这个赛场不可能又当前学校的队员,所以对当前学校来说,这个教室也是新开的
#include <bits/stdc++.h>
//#define int long long
const int N = 1e3 + 10;
const int INF = 0x3f3f3f3f;
using namespace std;
map<string, int> ans;
vector<int> room; // 记录每个赛场剩余位置
vector<string> order; // 记录学校的输入顺序
struct node
{
    string name;
    int cnt; // 剩余人数
    bool operator < (const node& t) const
    {
        return cnt < t.cnt;
    }
};
priority_queue<node> q;
signed main()
{
    int n, m;
    cin >> n >> m;
    for(int i = 0; i < n; i ++)
    {
        string name;
        int cnt;
        cin >> name >> cnt;
        // 记录学校顺序
        order.push_back(name);
        q.push({name, cnt});
    }
    while(q.size())
    {
        int cnt = q.top().cnt;
        string name = q.top().name;
        q.pop();

        if(cnt >= m)
        {
            room.push_back(0);
            ans[name] ++;
            if(cnt > m) q.push({name, cnt - m});
        }
        else
        {
            int ff = 0;
            for(int i = 0; i < room.size(); i ++)
            {
                if(room[i] >= cnt)
                {
                    room[i] -= cnt;
                    ans[name] ++;
                    ff = 1;
                    break;
                }
            }
            if(ff == 0)
            {
                room.push_back(m - cnt);
                ans[name] ++;
            }
        }
    }
    for(int i = 0; i < order.size(); i ++)
    {
        string name = order[i];
        cout << name << ' ' << ans[name] << endl;
    }
    cout << room.size() << endl;
    return 0;
}