#include<stdio.h>
struct{
int head, tail;
int data[1001]; //其实使用循环队列模仿更加省空间
int time; //这是每次出队的时候计算出队的人的时间的,初始为0表示8点
}queue[20], wait;
int startTime[1001];
int completionTime[1001];
int main()
{
int N, M, K, Q;
scanf("%d %d %d %d", &N, &M, &K, &Q);
int i = 0;
for(i = 0; i < K; i++){
int time = 0;
scanf("%d", &time);
if(i < N * M){ //先初始化柜台队列
int q = i % N;
queue[q].data[queue[q].tail++] = time;
startTime[i+1] = queue[q].time;
queue[q].time += time;
completionTime[i+1] = queue[q].time;//这里只是单纯填装队伍,至于能不能被服务就是另一件事情了
}//等于说填装队伍的时候已经计算了出队时间,注意题意指明入队后不可以换队伍
else{
wait.data[wait.tail++] = time;//初始化等待队列
}
}
for(i = 1; i < 540; i++){//计算等待队列顾客的完成时间,注意每名顾客的开始接待时间也很重要
//每分钟扫描一次所有队列,将其头位置的时间减1,并检查是否等于零
//如果有队头时间减一后等于零则wait队列出一个人进入该队列
//注意入队的人必定要出队无论截止时间是多少,所以入队时间要控制
if(wait.tail - wait.head > 0){
int j = 0;
for(j = 0; j < N; j++){//所有队列队头time减一
queue[j].data[queue[j].head]--;
if(queue[j].data[queue[j].head] == 0){
queue[j].head++;
queue[j].data[queue[j].tail++] = wait.data[wait.head++];
startTime[N*M+wait.head] = queue[j].time;
queue[j].time += wait.data[wait.head-1];
completionTime[N*M+wait.head] = queue[j].time;
}
}
}
else break;
}
if(wait.tail - wait.head > 0){//540分钟后表示队伍有剩余,全部赋值550表示不能服务
//这个坑也是看了https://blog.csdn.net/Joyceyang_999/article/details/82020758?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param
//博客才知道,之前忘了。
int num = N * M + wait.head + 1;
for(i = 0; i < wait.tail - wait.head; i++){
startTime[num + i] = 550;
}
}
for(i = 0; i < Q; i++){
int num = 0;
scanf("%d", &num);
if(startTime[num] < 540){
int h = completionTime[num]/60 + 8;
int m = completionTime[num]%60;
printf("%02d:%02d\n",h ,m);
}
else printf("Sorry\n");
}
return 0;
}
里面的那个博客写的比较好,可以参考。