#include <bits/stdc++.h>
using namespace std;
const int maxn = 5005;
string sname[maxn];
int renshu[maxn], pos[maxn],cnt[100*maxn];//cnt人数,pos第i个学校需要的考场数量,第i个考场剩余的人数
priority_queue<pair<int, int>> pq;//人数-学校编号,优先队列,人数大的学校排在前面,类似大根堆但更加方便
map<int, int> rest;
int main() {
int n, c;
cin >> n >> c;
for (int i = 1; i <= n; i++) {//注意其编号从1开始
cin >> sname[i] >> renshu[i];
pq.push({ renshu[i],i });//注意C++中pair数组语法
}
int kccnt = 0;//赛场数量
while (!pq.empty()) {
int k = pq.top().first;//学校剩余人数
int sno = pq.top().second;//学校编号
pq.pop();//注意本题最核心的队列思想即类似操统中的时间片轮转调度算法以及BFS相应实现算法
//本轮先弹出对其进行处理,一轮处理不完相应再在其队尾插入等待下一轮的处理并以此类推
pos[sno]++;//涉及一个考场
if (k >= c) {
cnt[++kccnt] = 0;//更新第i个考场剩余人数
k -= c;//更新对应学校剩余人数
if (k) {//一轮没有处理完等待下一轮处理
pq.push({k,sno});
}
continue;
}
//只要进入上面的判断即一定continue即不会入下
int flag = 0;//是否找到了满足需求的考场
for (int i = 1; i <= kccnt; i++) {//从小考场开始找
if (cnt[i] >= k) {
flag = 1;
cnt[i] -= k;
break;
}
}
if (!flag) cnt[++kccnt] = c - k;//如果其没有找到则相应新开辟一个考场
}
for (int i = 1; i <= n; i++) {
cout << sname[i] << " " << pos[i] << '\n';
}
cout << kccnt << '\n';
return 0;
}
L2-046 天梯赛的赛场安排
最新推荐文章于 2024-07-14 19:56:17 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)