题意
一个银行有n个窗口,每个窗口最多排m个人,多出去的人在黄线外等候,一共有k个人同时进入银行办理业务,每个人有一个办理业务所需要的时间,每个人会选择人数最少的窗口进行排队或者办理业务,若人数最少窗口相同的话选择序号最小的窗口。然后进行q次询问,询问编号为x的人办理完业务的时间为多少,银行每天8:00开门17:00关门,若在关门后办理业务输出sorry
思路
- 由于时间是从8点到17点所以,我们模拟时间来就可以了,用一个for循环来模拟时间,每一次判断排队第一个人办理业务的结束的时间是否为循环时间,若等于则将排第一个的人踢出,然后第二个人就变为第一个人开始办理业务,结束时间是当前循环时间加上他的办理时间
- 每个窗口的队伍可以用一个vector来模拟,第一个人可以用vector中的erase来去掉。
- 我们每次时间判断一下有没有队伍可以加入,如果有就去寻找一下人数最小的那个队伍去加入
- 有一点需要注意的是若开始办理的时间在17点之前(不包括17点)但是结束时间在17点或17点后,他也是算的而不能输出sorry
#include<bits/stdc++.h>
using namespace std;
struct node
{
int id;
int flag;
int end;
int con;
} a[1005];
vector<node>b[25];
queue<int>c;
int ans[1005];
int main()
{
memset(ans,-1,sizeof(ans));
int n,m,k,q;
scanf("%d%d%d%d",&n,&m,&k,&q);
for(int i=1; i<=k; i++)
{
a[i].id=i;
scanf("%d",&a[i].con);
int minn=m;
int pos=0;
for(int j=1; j<=n; j++)
{
if(minn>b[j].size())
{
minn=b[j].size();
pos=j;
}
}
if(pos&&b[pos].size()<m)
{
if(b[pos].size()==0)
{
a[i].flag=1;
a[i].end=a[i].con;
}
b[pos].push_back(a[i]);
}
else
c.push(i);
}
for(int i=0; i<540; i++)
{
int flag=0;
for(int j=1; j<=n; j++)
{
if(b[j].size()&&b[j][0].end==i)
{
flag=1;
ans[b[j][0].id]=i;
b[j].erase(b[j].begin());
if(b[j].size())
{
b[j][0].flag=1;
b[j][0].end=i+b[j][0].con;
}
}
}
while(!c.empty()&&flag)
{
int minn=m;
int pos=0;
for(int j=1; j<=n; j++)
{
if(minn>b[j].size())
{
minn=b[j].size();
pos=j;
}
}
if(pos&&b[pos].size()<m)
{
b[pos].push_back(a[c.front()]);
c.pop();
}
else
break;
}
}
for(int i=1; i<=n; i++)
if(b[i].size()!=0)
{
if(b[i][0].flag==1)
ans[b[i][0].id]=b[i][0].end;
}
while(q--)
{
int x;
scanf("%d",&x);
if(ans[x]!=-1)
printf("%.2d:%.2d\n",ans[x]/60+8,ans[x]%60);
else
printf("Sorry\n");
}
return 0;
}