题目链接:
题目说的比较清楚,模拟银行的排队系统,在黄线前的客户排好队,而且不能随意更换自己的位置,在黄线外的客户在未开始排队时是一个随意的状态,而且盯着哪个队伍比较短,就去那里排队。
输入:n窗口的数目,m黄线前的客户数量最大值,k客户总数,q需要查询的客户数,接下来k个数代表k个客户的时间,再起一行是需要查询客户的编号。
输出:每一位需要查询的客户的结束时间,如果这个时间在8:00~17:00之间,输出即可,否则输出Sorry。
这里使用一个结构体模拟窗口前的队列,poptime是队列第一个人的结束时间,endtime是队列最后一个人的结束时间,下面是代码:
#include#include #include #include using namespace std;struct node{ //结构体定义每个窗口的序列 int poptime,endtime; //poptime最前面人的结束时间,endtime最后面人结束的时间 queue q; //保存每一位顾客的需求时间};int main(){ int n,m,k,q,index = 1; //index? scanf("%d%d%d%d",&n,&m,&k,&q); //各个参数 vector time(k+1), result(k+1); //time保存每个人的需求时间,result存的是最终的结束时间 for(int i =1; i <= k; i++){ scanf("%d",&time[i]); // 输入需求时间 } vector window(n+1); //窗口结构体 vector sorry(k+1,false); //判断是否超过17:00 for(int i = 1; i <= m; i++){ //安排前m*n的人 for(int j = 1; j <= n; j++){ if(index <= k){ // 当前的人数小于客户总数,就是说客户总数大于m*n window[j].q.push(time[index]); //压入当前的时间消耗 if(window[j].endtime >= 540) //大于17:00 sorry[index] = true; window[j].endtime += time[index]; //此队列的最后时间要加上入队的时间 if(i == 1){ //最靠近窗口的那一行人 window[j].poptime = window[j].endtime; } result[index] = window[j].endtime; //记录下当前人的结束时间保存在result中,并且是提前计算出来 index++; } } } while(index <= k){ //当前人数大于m*n但是小于总人数 int tempmin = window[1].poptime,tempwindow = 1; //寻找最早结束的时间,并且重复寻找 for(int i = 2; i <= n; i++){ // if(window[i].poptime < tempmin){ //寻找最早结束时间的队列索引 tempwindow = i; tempmin = window[i].poptime; } } window[tempwindow].q.pop(); //将存的time[index]弹出去 window[tempwindow].q.push(time[index]); //再压入当前的time window[tempwindow].poptime += window[tempwindow].q.front(); //此队列最早时间往后拖延 if(window[tempwindow].endtime >= 540) sorry[index] = true; window[tempwindow].endtime += time[index]; //记录当前的最迟时间 result[index] = window[tempwindow].endtime; //提前计算出耗时,保存起来。 index++; } for(int i = 1; i <= q; i++){ int query,minute; scanf("%d",&query); minute = result[query]; if(sorry[query] == true){ printf("Sorry\n"); } else{ printf("%02d:%02d\n",(minute+480)/60,(minute+480)%60); } } return 0;}