PAT:银行排队问题:队列

1014. 银行排队

模拟银行柜台业务的办理逻辑,求出指定的顾客业务办理完成的预计时间。
借这道题可以对操作系统中的进程管理进行回顾。

题目大意:银行里有n个柜台窗口,每个窗口最多能同时容纳m个顾客排队,多余的站在大厅里。每个顾客有一个业务处理时间预期值。每当n个窗口的队列不是全满时,即可让黄线外的顾客入队,入队的规则是总是插入到当前队列长度最短的窗口中,如果有多个队列最短,则插入到窗口编号最小的窗口中,银行从早上8:00开始,下午5:00关门,求出指定的顾客业务处理完成时间。

这道题有一些需要注意的地方:
1. 如果某一顾客此时刚好业务处理完成,则将其踢出队列,如果他后面有人,则立即更新这个客户的开始服务时间(starttime),如果他后面没有人,则从黄线外拉一个客户入队,并立即更新其starttime,注意是立即,而不是下一分钟。

2.银行是17:00关门,如果客户A是17:00前接收到了服务,则即使过了17:00,客户A依然可以完成业务处理,而且要输出他的完成时间,不能sorry,而如果客户A在17:00整或之后想办理业务,则不好意思,sorry

3.窗口的队列做成循环队列,处理时会带来很大方便

PS:
这里用到了元素为queue的数组,事实上数组元素还可以是stack等数据类型。

#include<stdlib.h>
#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<limits.h>
#include<cmath>
#include<set>
#include<map>
#include<utility>
using namespace std;

int main()
{
    int n,m,k,q;
    int processTime[1005]={
  0};
    queue<int> que[25];
    int LeaveTime[1005]={
  0};    
    int Timebase[25] = {
  0};  

    cin>>n>>m>>k>>q;
    for(int i=0;i<k;i++) cin>>processTime[i];

    int index;
    int top=0;
    //i表示窗口数,Timebase表示窗口i上当前客户完成业务办理后的时间
    for(int i=0;top<n*m && top<k;top++) {
        que[i].push(top);
        LeaveTime[top] = Timebase[i]+processTime[top];  
        Timebase[i] = LeaveTime[top];  
        i = (i+1)%n;  
    }
    //n*m个客户都排好了队,剩余(k-n*m)个客户等在大厅里,等待排队
    for(;top<k;top++) {
        int min_wait = INT_MAX;
        int found = false;
        //寻找当前n个窗口中最早完成1个客户业务办理的窗口
        for(int j=0;j<n;j++) {  
            int cus = que[j].front();  
            if(min_wait > LeaveTime[cus]) {  
                min_wait = LeaveTime[cus];  
                index = j;
                found = true;             
            }
        }
        //把在等待的下一个客户排在最先完成业务的那个窗口           
        que[index].pop();    
        que[index].push(top);  
        LeaveTime[top] = Timebase[index] + processTime[top];    
        Timebase[index] = LeaveTime[top];  
    }  

    while(q--) {  
        
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值