返回目录
题意
某银行有N个窗口,每个窗口前最多可以排M个人。现在有K位客户需要服务,每位客户的服务时长已知。假设所有客户均在08:00按客户编号次序等在黄线外,且如果有窗口的排队人数没有排满(没有达到M人),当前在黄线外的第一一 个客户就会选择这样的窗口中排队人数最少的窗口去排队(排队人数相同时,选择窗口序号最小的窗口去排队)。给出Q个查询,每个查询给出一位客户的编号,输出这位客户的服务结束时间。注意:如果一个客户在17:00之后(含17:00)还没有被服务,则不再服务,输出Sory;而如果一个客户在 17:00前被服务,那不管服务时间多久,都会服务完。
样例(可复制)
2 2 7 5
1 2 6 4 3 534 2
3 4 5 6 7
//output
08:07
08:06
08:10
17:00
Sorry
注意点
- 如果客户在17.00前进行服务,就算服务结束在17.00后,也要输出。
- 把时间转换成分钟作为基本单位处理起来更方便。
#include<bits/stdc++.h>
using namespace std;
const int maxnode=1111;
int n,m,k,q,query;
int ans[maxnode],need[maxnode];//ans存放服务结束时间,need存储服务需要时间
struct window{
int endtime,poptime;//当前窗口最后服务时间,队首客户的服务结束时间
queue<int> q;
}win[20];
int gettime(int h,int m) {
return h*60+m;
}
int main(){
cin>>n>>m>>k>>query;//窗口数,窗口人口上限,客户数,查询数
for(int i=0;i<k;i++)scanf("%d",&need[i]);
for(int i=0;i<n;i++){//初始化所有窗口
win[i].endtime=win[i].poptime=gettime(8,0);
}
int now=0;//客户入队编号
for(int i=0;i<min(n*m,k);i++){
win[now%n].q.push(now);
win[now%n].endtime+=need[now];
if(now<n)win[now].poptime=need[now];
ans[now]=win[now%n].endtime;
now++;
}
for(;now<k;now++){
int idx,minn=INT_MAX;
for(int i=0;i<n;i++){
if(win[i].poptime<minn){
idx=i;
minn=win[i].poptime;
}
}
window& w=win[idx];
w.q.pop();
w.q.push(now);//now进入黄线内窗口idx处进行排队
w.endtime+=need[now];
w.poptime+=need[w.q.front()];
ans[now]=w.endtime;
}
for(int i=0;i<query;i++){
scanf("%d",&q);
if(ans[q-1]-need[q-1]>=gettime(17,0))printf("Sorry\n");
else printf("%02d:%02d\n",ans[q-1]/60,ans[q-1]%60);
}
return 0;
}