PAT 1014. Waiting in Line (30) 队列模拟 +简单消费者生产者

来源:互联网 发布:诺贝尔经济学奖知乎 编辑:程序博客网 时间:2024/06/07 03:39
#include<iostream>#include<cstdio>#include<algorithm>#include<queue>#include<string.h>#include<cmath>#include<string>using namespace std;//跪在题意理解(搜索树构建)和代码错误/*************************题意:有N个窗口,每个窗口可排队M个人。排不进去的人在黄线外等待。只要队伍有空隙,就可排入,选序号最小的队伍排入。17点之后停止“开始服务”即17点之后不准开始新的服务但是17点之前的服务是可以进行到完成的。。。尼马题目好坑啊*************************//************************求解要点:1.直接模拟队列,重点为计算各队的首位出队时间以及最后判断是否不可服务,注意题目陷阱************************//***********************笔记:*********************/#define M 1200#define INF 0xfffffffint cust[M];struct WinQ{queue<int> q;int outtime;int id;};WinQ wq[M];int cusqt[M];int main(){int n,m,k,q,i,ci;scanf("%d%d%d%d",&n,&m,&k,&q);queue<int> yq;int qmax=m;for(i=0;i<k;i++){scanf("%d",&cust[i]);yq.push(i);}int cus;//安排前N个顾客for(i=0;i<n;i++){wq[i].outtime=INF;if(!yq.empty()){ci=yq.front();yq.pop();wq[i].q.push(ci);wq[i].outtime = cust[ci];}}//把人排满队伍先while(wq[n-1].q.size()<qmax && !yq.empty()){for(i=0;!yq.empty() && i<n;i++){if(wq[i].q.size()<qmax){ci=yq.front();yq.pop();wq[i].q.push(ci);}}}int tmin,id,lmin;while(1){//以出队时间排序。不用考虑序号和长度//只要当前只有该队出队,则一定有人补上或后面没人补了tmin=INF;for(i=0;i<n;i++){if(wq[i].outtime<tmin){tmin=wq[i].outtime;id=i;lmin=wq[i].q.size();}}//队伍全空,则breakif(tmin==INF)break;//计算出队时间ci=wq[id].q.front();cusqt[ci]=wq[id].outtime;wq[id].q.pop();//选等待者入队if(!yq.empty()){ci=yq.front();yq.pop();wq[id].q.push(ci);}//出队时间增加//若已空队说明没人等待了,取消服务。if(wq[id].q.empty())wq[id].outtime=INF;elsewq[id].outtime += cust[wq[id].q.front()];}int quest,h,custime;for(i=0;i<q;i++){scanf("%d",&ci);custime=cusqt[ci-1]; //结束服务时间//结束服务时间-所花时间=开始时间,开始时间在17点及17点之后的为sorryif(custime -cust[ci-1] < 540) //注意是小于0{h=custime/60 + 8;m=custime%60;printf("%02d:%02d\n",h,m);}else printf("Sorry\n");}return 0;}