PAT (Advanced Level) Practice 1014 Waiting in Line

题目链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805498207911936

题目说的比较清楚,模拟银行的排队系统,在黄线前的客户排好队,而且不能随意更换自己的位置,在黄线外的客户在未开始排队时是一个随意的状态,而且盯着哪个队伍比较短,就去那里排队。

输入:n窗口的数目,m黄线前的客户数量最大值,k客户总数,q需要查询的客户数,接下来k个数代表k个客户的时间,再起一行是需要查询客户的编号。

输出:每一位需要查询的客户的结束时间,如果这个时间在8:00~17:00之间,输出即可,否则输出Sorry。

这里使用一个结构体模拟窗口前的队列,poptime是队列第一个人的结束时间,endtime是队列最后一个人的结束时间,下面是代码:

#include <iostream>
#include<stdio.h>
#include<vector>
#include<queue>
using namespace std;
struct node{               //结构体定义每个窗口的序列
    int poptime,endtime;  //poptime最前面人的结束时间,endtime最后面人结束的时间
    queue<int> q;          //保存每一位顾客的需求时间

};
int main()
{
    int n,m,k,q,index = 1;                  //index?
    scanf("%d%d%d%d",&n,&m,&k,&q);          //各个参数
    vector<int> time(k+1), result(k+1);      //time保存每个人的需求时间,result存的是最终的结束时间
    for(int i =1; i <= k; i++){
        scanf("%d",&time[i]);                // 输入需求时间
    }
    vector<node> window(n+1);        //窗口结构体
    vector<bool> 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;
}

 

转载于:https://www.cnblogs.com/huhusw/p/9523252.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值