题意:大概是说银行的队伍分黄线前和黄先后两种,黄线前有n个柜台,每个柜台可以排m个人,黄先后只站一排,最前面的人总是会站到黄线前人最少且序号尽量小的队伍中去,银行早上8点开门,17点关门,已知每个用户办理业务所需的时间,求每个用户何时能办完业务,如果一个用户的业务在17点之前还没开始就输出sorry
思路:思路还是比较清晰的,我们可以很容易的知道前n*m个人,会横向站到黄线前的队伍中去,所以他们的时间都可以容易的求出来,主要问题是黄线后的人,很明显,他始终站到黄线前第一个走的人的队伍中(同时的话序号最小),所以我们对黄线前的所有用户建一个优先队列,这样每次队首元素所在的队伍序号就是黄先后第一个人回去的队伍,这样只要每次记录每个队伍所有人业务结束的时间,就可以知道下一个人在什么时候结束业务,注意记录sorry的情况
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
struct PP
{
int time,id;
};
struct QQ
{
bool operator() (const PP &a,const PP &b) const{
if(a.time==b.time) return a.id>b.id;
return a.time>b.time;
}
};
priority_queue<PP,vector<PP>,QQ> Q;
int n,m,k,q;
int T[1005],pro[1005],ans[1005];
bool mark[1005];
int main()
{
int i,j,temp=-1;
memset(mark,false,sizeof(mark));
scanf("%d%d%d%d",&n,&m,&k,&q);
for(i=0;i<k;i++)
scanf("%d",&T[i]);
for(i=0;i<n;i++) pro[i]=8*60;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
temp++;
if(temp>=k) break;
PP New;
if(pro[j]>=17*60) mark[temp]=1;
pro[j]+=T[temp];
ans[temp]=pro[j];
New.time=pro[j];
New.id=j;
Q.push(New);
}
}
while(temp++<k)
{
PP t=Q.top();
Q.pop();
if(pro[t.id]>=17*60) mark[temp]=1;
pro[t.id]+=T[temp];
ans[temp]=pro[t.id];
PP New;
New.id=t.id;
New.time=pro[t.id];
Q.push(New);
}
for(i=0;i<q;i++)
{
int a;
scanf("%d",&a);
a--;
if(!mark[a])
printf("%02d:%02d\n",ans[a]/60,ans[a]%60);
else puts("Sorry");
}
return 0;
}