1014 Waiting in Line (30分)佇列模擬題
阿新 • • 發佈:2020-08-04
題目
https://pintia.cn/problem-sets/994805342720868352/problems/994805498207911936
題意
N個視窗,K個人去辦事,每個視窗黃線內可容納M個人,黃線外排一對,問每個人的完成時間
Sample Input:
2 2 7 5
1 2 6 4 3 534 2
3 4 5 6 7
Sample Output:
08:07
08:06
08:10
17:00
Sorry
題解
N個視窗對應N個佇列queue<>Q[i],黃線外一個佇列queue<>T
先T中的人按順序塞進Q中
之後每次找隊頭time最小的一個佇列進行模擬,每pop掉一個,馬上T中補上一個
雖然17:00關門,但17:00還在服務的人不能趕走~
code
/*************************** Hello World! ***************************/ #include <bits/stdc++.h> using namespace std; typedef long long ll; struct node{ ll time; ll id; node(ll _t,ll _i):time(_t),id(_i){} }; ll N,M,K,Q1; queue<node>T;//排隊 queue<node>Q[21];//視窗 ll ans[1006]; int d[1006];//每個人需要的時間 void print_time(int t,ll now) { if(now-d[t]>=540) { printf("Sorry\n"); return ; } int HH=8,MM=0; HH+=now/60; MM+=now%60; printf("%02d:%02d\n",HH,MM); } int main() { scanf("%lld%lld%lld%lld",&N,&M,&K,&Q1); for(ll i=1;i<=K;i++) { ll x; scanf("%lld",&x); d[i]=x; T.push(node(x,i)); } //先塞滿黃線內 ll f=0; for(ll i=1;i<=M && !f;++i)//M行 { for(ll j=1;j<=N;++j) { if(T.empty()) { f=1; break; } Q[j].push(T.front()); T.pop(); } } ll now=0;//8:00 ll aaa=K; while(aaa--) { //找出所有隊頭的最小值 ll p=-1,mm=inf; for(ll i=1;i<=N;++i) { if(Q[i].empty()) continue; ll temp=Q[i].front().time; if(temp<mm) { p=i; mm=temp; } } //每個隊頭時間-mm for(ll i=1;i<=N;++i) { if(Q[i].empty()) continue; Q[i].front().time-=mm; } //記錄時間,彈出Q[p]的隊頭 if(now<600) now+=mm; ans[Q[p].front().id]=now; Q[p].pop(); //如果黃線外還有人,加入Q[p] if(!T.empty()) { Q[p].push(T.front()); T.pop(); } } while(Q1--) { ll xx; scanf("%lld",&xx); print_time(xx,ans[xx]); } return 0; } /*************************** The end! ***************************/