L2-046 天梯赛场的安排(STL模拟)

天梯赛场的安排

解题思路

FB70319368DD30C13F9483A285F0CD01
太糟糕了,题干长,模拟复杂的一道题

本题有以下几个注意点:

  • 每一轮都是对人数最多的学校分配赛场,所以要用一个优先队列。

  • 题目要求计算每个学校要联系的监考老师数量,且题意要求为每个学校都要联系所在考场的监考老师,因此,需要计算出每个学校的学生安排在了几个考场

  • 本题数据不够严谨,或者说本题要求较低,因为如果存在两个人数一样的学校,该怎么处理呢,题目没有明确说明,但是这对答案不会有影响,因为相等的几个元素实际上是等价的,最后统计的联系人数是不变的,但是实际上如果要考虑实际情况,这里一定是有问题的。但是为了方便,我们这里还是没考虑这一点

下面是赛场安排的过程:

  1. 把队头元素拿出来,记数量为cnt,如果cnt 大于等于 赛场容量,就要开一间新的赛场,把人放进去,如果 cnt 大于 赛场容量,说明还有剩下来的,就放回队中。这时候要记录联系人加一

  2. 如果cnt 小于 赛场容量,就找赛场容量大于等于cnt且编号最小的赛场安排进去。然后更新赛场的容量,记录联系人加一。更新容量的时候要把原来的赛场信息删除,更新后再插入。

  3. 如果找不到,就新开一个,这时候赛场必然是没排满的,所以直接更新赛场容量。

tip:本来我想使用二分查找,但是二分查找的前提是有序,但是这里的赛场不能排序,所以只能遍历了,当然可以使用set,但是那种复杂的容器我这里不想使用,因为太复杂了,jiangly_fan_fan_fan就是特别复杂的容器模拟,很难学会,尤其后面涉及到赛场容量的更新时,会很裹

ac✅️代码(也可以用数组代替结构体,不过看起来有点复杂)

//接下来的代码我参考了gemini,和jiangly_fan_fan_fan的,不过二者都有优缺点,本代码是我总结出最好理解的,不喜欢结构体的可以换成数组
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;

struct School{
	string name;
	int teachers = 0;
	int remain;
	
};

int main()
{
	int n,m;
	cin>>n>>m;
	
	School sch[5010];
	
	priority_queue<pair<int,int>> line;
	
	for(int i = 0 ;i < n ; i++)
	{
		cin>>sch[i].name>>sch[i].remain;
		line.push({sch[i].remain,i});//这里加入的是它在结构体数组中的索引
	}
	
	vector<int> rooms;//直接放容量即可,因为每个索引就是赛场编号
	
	while(line.size())
	{
		auto [cnt,id] = line.top();
		line.pop();
		
		if(cnt >= m)
		{
			rooms.push_back(0);
			sch[id].teachers ++;
			if(cnt > m) line.push({cnt - m,id});
		}
		else
		{
			
			int index = -1;
			
			for(int i = 0 ; i < rooms.size() ; i ++)
			{
				if(rooms[i] >= cnt)
				{
					index = i;
					break;
				}
			}
			if(index != -1)
			{
				
				rooms[index] -= cnt;
				sch[id].teachers ++;
				
			}
			else
			{
				rooms.push_back(m - cnt);
				sch[id].teachers ++;
			}
		}
	}
	
	for(int i = 0 ; i < n ; i++)
	{
		cout<<sch[i].name<<" "<<sch[i].teachers<<"\n";
		
	}
	
	cout<<rooms.size()<<endl;
	
	return 0;
}
posted @ 2026-03-20 13:53  shuiwangrenjia  阅读(32)  评论(0)    收藏  举报