1. 读取每位顾客所需时间时进行窗口排队并入队
2. 若遍历窗口发现队伍均已满,则需要出队
3. 队满出队:遍历窗口队列,比较每个队列队头元素的finish[],在finish[]最小的那个队列进行队头出队、队尾入队操作
4. 查询时注意是要对不能在17:00(不含17:00)前被服务的顾客say sorry,所以要判断的是开始时间start[],而不是结束时间finish[]
#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <set>
#include <vector>
#include <iomanip>
#include <map>
#include <ctime>
#include <cstdlib>
#include <queue>
#include <deque>
#define ll long long
#define MAX_SIZE 1 << 20
using namespace std;
deque<int> deq[22];
int n, m, k, q, t[1010], start[1010], finish[1010];
int endt = 9 * 60;
int main() {
cin >> n >> m >> k >> q;
for(int i = 1; i <= k; i++) {
cin >> t[i];
int p = 1;
for(int j = 2; j <= n; j++)
if(deq[j].size() < deq[p].size()) p = j;
if(deq[p].size() >= m) { // 满了,要出队
// 遍历窗口找到最早有空位的窗口
int mint = 0x3f;
p = 1;
for(int j = 1; j <= n; j++) {
int first = deq[j].front();
if(finish[first] < finish[deq[p].front()]) {
mint = finish[first];
p = j;
}
}
deq[p].pop_front(); // 从队头出队
}
// 入队
int last = 0;
if(!deq[p].empty())
last = deq[p].back();
start[i] = start[last] + t[last]; // 根据现有队列队尾元素的开始时间和所需时间计算当前顾客的开始时间
finish[i] = start[i] + t[i];
deq[p].push_back(i); // 加入队伍
}
while(q--) {
int x;
cin >> x;
if(start[x] >= endt) cout << "Sorry" << endl; // 不能在17:00之前被服务的顾客要say sorry
else printf("%02d:%02d\n", 8 + finish[x] / 60, finish[x] % 60);
}
}