传送门
这道题思路倒也不是 很难,主要采用模拟队列的思想,模拟N个窗口,分别进行入队和出队操作;
建立结构体,tfir是入队时间,q是排队时间的队列,tend是出队的时间(比较懒,所以没有起很长的变量名字),再用peo[i]存第i个人的prosess时间。per[i]记录第i个人结束的时间;
比较坑的一点,之前一直wa,银行是在17:00结束服务,而不是17:00就不干了,所以如果你在17:00之前排到你,但是你要进行很长时间,超过17:00也是可以的(可能是我自己比较蠢,正常银行不都这样,还是借鉴柳神的代码才明白)所以在此设置sorry数组,如果前一个人的出队时间>=17:00,那么sorry[i]==true;不过现在还是有一个点没有过,待更新,望网友发现能够指正。发现上面函数里对540的判断力忘加了等号导致第四个测试点不过。现代码已经更正。
#include<bits/stdc++.h>
using namespace std;
struct windows{
int tfir;
queue<int> q;
int tend;
};
int per[1010];bool sorry[1010];
void init(windows wdw[],int &K,int n,int m,int peo[]){
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(wdw[j].tend>=540)sorry[K]=true;
wdw[j].q.push(peo[K]);
wdw[j].tend+=peo[K];
per[K]=wdw[j].tend;
K++;
}
}
for(int i=1;i<=n;i++){
wdw[i].tfir=wdw[i].q.front();//cout<<wdw[i].tfir<<endl;
}
}
void cal(int t,int &hu,int &mu){
hu=8+(t/60);
mu=t%60;
}
int main(){
int n,m,k,Q;
int peo[1010];
windows wdw[1010];
scanf("%d%d%d%d",&n,&m,&k,&Q);
for(int i=1;i<=k;i++){
scanf("%d",&peo[i]);
}
int K=1;
init(wdw,K,n,m,peo);
while(K<=k){
int temin=wdw[1].tfir,flag=1;
for(int i=2;i<=n;i++){
if(wdw[i].tfir<temin){
temin=wdw[i].tfir;
flag=i;
}
}
if(wdw[flag].tend>=540)sorry[K]=true;
wdw[flag].q.pop();
wdw[flag].q.push(peo[K]);
wdw[flag].tend+=peo[K];
per[K]=wdw[flag].tend;
wdw[flag].tfir+=wdw[flag].q.front();
K++;
}
for(int i=1;i<=Q;i++){
int temp,hu,mu;
scanf("%d",&temp);
cal(per[temp],hu,mu);
if(!sorry[temp])
printf("%02d:%02d\n",hu,mu);
else printf("Sorry\n");
}
return 0;
}