1014 Waiting in Line(30)& 1017 Queueing at Bank(25)

目录

🧡1014 Waiting in Line

解析

易错点

代码

🧡1017 Queueing at Bank

解析

易错点

代码


💟这里是CS大白话专场,让枯燥的学习变得有趣!

💟没有对象不要怕,我们new一个出来,每天对ta说不尽情话!

💟好记性不如烂键盘,自己总结不如收藏别人!

💌1014和1017这两个排队题真的搞死我了[○・`Д´・ ○],记录一些踩坑点!

🧡1014 Waiting in Line

题目链接:PTA | 程序设计类实验辅助教学平台

解析

💌银行有N个窗口,每个窗口在黄线内可排M个人,如果黄线内没有排满就入队(按窗口顺序入队),排满的话就在黄线外等待,黄线内出一个进一个,如果同时出了多个,选窗口小的进。营业时间8:00-17:00,如果客户在17:00及之后还没被服务,就不再服务,如果已经开始服务了,就要完成服务。

🍠输入

第一行:窗口数N,黄线内每个窗口最大容量M,客户数K,问询结束时间的客户数Q。

第二行:K个客户的处理时间(min)。

第三行:问询的客户编号。

易错点

🍠黄线外选取最小的出列窗口。

🍠查询的时候编号要减一,因为存储的时候索引是从0开始的~

代码

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;

struct Customer{
    int startTime,processTime,endTime;
}customer[1000];

int main(){
    int N,M,K,Q; //N:窗口 M:一队长度 K:总人数 Q:需要告知时间的人
    cin >> N >> M >> K >> Q;
    for(int i=0;i<K;i++) cin >> customer[i].processTime;
    queue<Customer> windows[N];
    int openTime = 8*60, closeTime = 17*60;
    // 入队
    for(int i=0;i<K;i++){
        // 排黄线内
        if(i<N*M){
            int window = i%N;
            if(i<N){
                customer[i].startTime = openTime;
                customer[i].endTime = openTime + customer[i].processTime;
            }else{
                customer[i].startTime = windows[window].back().endTime;
                customer[i].endTime = customer[i].startTime + customer[i].processTime;
            }
            windows[window].push(customer[i]);
        }
        // 排黄线外
        else{
            int window = 0;
            for(int j=1;j<N;j++){
                if(windows[j].front().endTime<windows[window].front().endTime){
                    window = j;
                }
            }
            windows[window].pop();
            customer[i].startTime = windows[window].back().endTime;
            customer[i].endTime = customer[i].startTime + customer[i].processTime;
            windows[window].push(customer[i]);
        }
    }
    int id;
    while(Q--){
        cin >> id;
        if(customer[id-1].startTime < closeTime){
            printf("%02d:%02d\n",customer[id-1].endTime/60,customer[id-1].endTime%60);
        }
        else{
            cout << "Sorry" << endl;;
        }
    }
    return 0;
}

🧡1017 Queueing at Bank

题目链接:PTA | 程序设计类实验辅助教学平台

解析

💌银行有N个客户,K个窗口,客户来了排成一队,选择空闲窗口服务,没有则继续排队等待,求,求平均等待时长。营业时间8:00-17:00,如果客户8:00之前到,要等到8:00开始服务,如果客户在17:00之后到,就不再为其服务,如果已经到了,加班加点也要完成服务(没见过这么敬业的银行(キ`゚Д゚´)!!)。可以不用队列来做,直接用数组lastTime记录当前每个窗口结束时间即可。

易错点

🍠平均是对有效服务客户的平均,没有被服务的客户不算在内。最好一开始读数据的时候就把不符合的客户剔除,不然后面测试点4一直不通过。。

🍠等待时间的计算要用到达时间和窗口结束时间比较,如果在结束之前到则需要计算,如果在结束之后到则不用等待。

🍠选择当前最快结束或空闲的服务窗口排队,如果需要等待,则该客户结束时间从窗口结束服务时间算起,如果不用等待,则从到达时间算起。

🍠如果没有有效服务,输出0.0。

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

struct Customer{
    int time,pro;
    int wait = 0;
}cus[10002];

bool cmp(Customer cus1, Customer cus2){
    return cus1.time < cus2.time;
}

int main(){
    int openTime = 8*60*60, closeTime = 17*60*60;
    int N,K; //N:总人数 K:窗口
    int success = 0; //记录有效人数
    cin >> N >> K;
    for(int i=0;i<N;i++){
        int hour,min,sec,pro;
        scanf("%d:%d:%d %d",&hour,&min,&sec,&pro);
        int time = hour*60*60+min*60+sec;
        if(time>=closeTime || pro>3600) continue;
        cus[success].time = time;
        cus[success].pro = pro*60;
        success++;
    }
    sort(cus,cus+success,cmp);
    int lastTime[K]; //记录每个窗口当前队伍结束时间
    //初始化 
    for(int i=0;i<K;i++){
        lastTime[i] = openTime;
    }
    for(int i=0;i<success;i++){
        //前K个人
        if(i<K){
            cus[i].wait = max(openTime-cus[i].time,0);
            lastTime[i] = max(openTime,cus[i].time)+cus[i].pro;
        }
        else{
            int shortTime = lastTime[0];
            int window = 0;
            for(int j=1;j<K;j++){
                //找当前最短的队伍
                if(lastTime[j]<shortTime){
                    shortTime = lastTime[j];
                    window = j;
                }
            }
            //排到最短的队伍后面
            cus[i].wait = max(lastTime[window]-cus[i].time,0);
            //如果等待则从上个人结束时间算起,如果没等则从到达时间算起
            lastTime[window] = max(lastTime[window],cus[i].time)+cus[i].pro;
         }
    }
    
    if(success){
        float totalTime = 0;
        for(int i=0;i<success;i++){
            totalTime += cus[i].wait;
        }
        float ave = (totalTime/60)/success;
        printf("%.1f\n",ave);
    }
    else printf("%.1f\n",0);
    return 0;
}

  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值