1014 Waiting in Line(不简单的STL模拟)
解题思路
要动态维护,我刚开始使用的是优先队列,pair,让人数为first,second为窗口编号,这样就能按照题目要求的“先找到人数最少,再找到编号最小”。然而
后面发现,这样无法确定等待的人该进哪个窗口,即什么时候有人办理好的问题我无法解决。
后来发现,可以用一个queue
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;
}

浙公网安备 33010602011771号