解法:
模拟双端队列。刚开始的N*M个客户一次排队到窗口,并计算一下他们完成服务的时间点。对于每一个后面的人,看哪儿一个窗口最早有人出队,则排在次队,根据队尾的人计算一下此人的结束时间。
最后判断如果一个人的开始服务时间>=17:00,则sorry。
#include <bits/stdc++.h> # define LL long long using namespace std; int p[1001]; int f[1001]; int window[20]; int main(){ int N,M,K,Q; scanf("%d%d%d%d", &N, &M, &K, &Q); for(int i=1;i<=K;i++){ scanf("%d", &p[i]); } memset(f,-1,sizeof(f)); for(int i=0;i<N;i++) window[i]=8*60; vector<deque<int>> qs(N); int w=0; int id=1; for(id=1;id<=K && id<=N*M;id++){ if(qs[w].empty()) f[id]=8*60+p[id]; else{ f[id]=f[qs[w].back()]+p[id]; } qs[w].push_back(id); w=(w+1)%N; } while(id<=K){ int minend=INT_MAX; int wid=0; for(int i=0;i<N;i++){ if(f[qs[i].front()]<minend){ wid=i; minend=f[qs[i].front()]; } } if(minend>=17*60) break; qs[wid].pop_front(); f[id]=f[qs[wid].back()]+p[id]; qs[wid].push_back(id); id++; } for(int i=0;i<Q;i++){ int q; scanf("%d", &q); if(f[q]==-1 || f[q]-p[q]>=17*60) printf("Sorry "); else { int mm=f[q]%60; int hh=f[q]/60; printf("%02d:%02d ", hh, mm); } } return 0; }