1014 Waiting in Line(不简单的STL模拟)

本题传送门

解题思路

要动态维护,我刚开始使用的是优先队列,pair,让人数为first,second为窗口编号,这样就能按照题目要求的“先找到人数最少,再找到编号最小”。然而

后面发现,这样无法确定等待的人该进哪个窗口,即什么时候有人办理好的问题我无法解决。

后来发现,可以用一个queue q[30];队列数组,每一个队列代表一个窗口,其内容为每个人的时间,数组索引就是窗口编号,时间元素就是窗口人数 。

ac✅️代码

#include<bits/stdc++.h>

using namespace std;

queue<int> a[30];//每个队列里放时间,时间元素的个数就代表着人数,数组索引就是窗口编号
int beg[1010],fin[1010];
int n,m,k,q;
int main()
{
    cin>>n>>m>>k>>q;
    for(int i = 1 ; i <= k ;  i++)
    {
		int t;
		cin>>t;
		
		int choice = 0;
		//先找人数最少的
		for(int j = 0 ; j < n ; j ++)
		{
			if(a[choice].size() > a[j].size())
			{
				choice = j;
			}
		}
		
		
		//如果找到的人数最少的窗口都已经满了
		//就去找最先有空位的窗口
		//由于每个队列的队首就是当前人需要的时间,只要找到最小的就可以了
		if(a[choice].size() == m)
		{
			for(int j = 0 ; j < n ; j++)
			{
				if(a[choice].front() > a[j].front())
				{
					choice = j;
				}
			}
		}
		//这里我们采用的是预入队,即直接计算它最后会到哪个队
		beg[i] = (a[choice].size() ? a[choice].back() : 0);
		
		if(a[choice].size() == m) a[choice].pop();//如果满了,需要先将队首出队
		fin[i] = beg[i] + t;
        //由上个人的结束时间算出当前人的结束时间。
		a[choice].push(fin[i]);
	}
	
	for(int i = 0 ; i < q ; i ++)
	{
		int x;
		cin>>x;
		if(beg[x] >= 540)
		{
			cout<<"Sorry"<<endl;
			
		}
		else printf("%02d:%02d\n",8 + fin[x]/60, fin[x]%60);
		
	}
    
    return 0;
}

posted @ 2026-04-04 17:25  shuiwangrenjia  阅读(3)  评论(0)    收藏  举报