题目描述
输入样例
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
思路
模拟
存储结构
1.用结构体数组存储学校信息,包括学校编号,姓名,联系的监考老师数量
2.用优先队列存储每个学校的人数及其编号==(优化排序的复杂度)==
3.用一个数组存储空教室的信息
具体流程
1.不断取出优先队列的头元素,直至队列元素为空
2.判断当前学校的人数stu_num与教室最大容量c的关系
①stu_num >= c,开辟新房间,更新学校人数,联系监考老师+1,如果在安排后该学校仍有未安排进考场的学生,则再次将其入队
②stu_num < c,搜索已有房间,用flag标志是否有可用房间,如果有将其放入,否则开辟新房间。最后将该学校的未安排人数置零,联系监考老师+1,不用再次入队
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
typedef struct
{
int id; //学校编号
string name; //学校名称
int coach_num; //教练数量
}school;
vector<school> sch_info; //学校信息数组
vector<int> room; //房间数组
priority_queue<PII, vector<PII>, less<PII>> sch_person; //学校人数数组
int main()
{
int n, c;
cin >> n >> c;
string name;
int num;
for(int i = 0; i < n; i ++)
{
cin >> name >> num;
sch_info.push_back({i, name, 0});
sch_person.push({num, i});
}
int cnt = 0; //房间数量
while(sch_person.size())
{
//取出队首元素,即为未安排人数最多的学校
PII temp = sch_person.top();
sch_person.pop();
//取出该学校信息
int &stu_num = temp.first;
int sch_id = temp.second;
if(stu_num >= c)
{
cnt ++; //开一个新房间
stu_num -= c; //更新该学校未安排考场的人数
sch_info[sch_id].coach_num ++; //对应学校需要联系的监考人+1
if(stu_num) sch_person.push(temp); //如果该学校仍有人未安排,再次将其入队
}
else
{
bool flag = false; //标记已存在的教室是否有可用的
for(int i = 0; i < room.size(); i ++)
{
if(room[i] + stu_num <= c)
{
flag = true;
room[i] += stu_num; //更新空教室的剩余人数
break;
}
}
if(!flag) //没有教室可用
{
cnt ++; //新开一个教室
room.push_back(stu_num);
}
sch_info[sch_id].coach_num ++;
stu_num = 0;
}
}
for(int i = 0; i < n; i ++)
cout << sch_info[i].name << " " << sch_info[i].coach_num << endl;
cout << cnt << endl;
return 0;
}
欢迎大家批评指正!!!