PTA 银行排队问题之单队列多窗口加VIP服务 队列+模拟

假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙。当有窗口空闲时,下一位顾客即去该窗口处理事务。当有多个窗口可选择时,假设顾客总是选择编号最小的窗口。

有些银行会给VIP客户以各种优惠服务,例如专门开辟VIP窗口。为了最大限度地利用资源,VIP窗口的服务机制定义为:当队列中没有VIP客户时,该窗口为普通顾客服务;当该窗口空闲并且队列中有VIP客户在等待时,排在最前面的VIP客户享受该窗口的服务。同时,当轮到某VIP客户出列时,若VIP窗口非空,该客户可以选择空闲的普通窗口;否则一定选择VIP窗口。

本题要求输出前来等待服务的N位顾客的平均等待时间、最长等待时间、最后完成时间,并且统计每个窗口服务了多少名顾客。

输入格式:

输入第1行给出正整数N(≤),为顾客总人数;随后N行,每行给出一位顾客的到达时间T、事务处理时间P和是否VIP的标志(1是VIP,0则不是),并且假设输入数据已经按到达时间先后排好了顺序;最后一行给出正整数K(≤)—— 为开设的营业窗口数,以及VIP窗口的编号(从0到K−1)。这里假设每位顾客事务被处理的最长时间为60分钟。

输出格式:

在第一行中输出平均等待时间(输出到小数点后1位)、最长等待时间、最后完成时间,之间用1个空格分隔,行末不能有多余空格。

在第二行中按编号递增顺序输出每个窗口服务了多少名顾客,数字之间用1个空格分隔,行末不能有多余空格。

输入样例:

10
0 20 0
0 20 0
1 68 1
1 12 1
2 15 0
2 10 0
3 15 1
10 12 1
30 15 0
62 5 1
3 1

输出样例:

15.1 35 67
4 5 1

调了整整一下午,真的恶心,注意看清加粗字体的要求,用队列模拟就行了,因为之前用结构体写过好几次队列了,这次就偷懒直接用STL里的了,代码如下(因为网上代码多是用时间流逝模拟,所以贴出我的代码以供交流学习,还望不要抄袭作业,毕竟可能会查重的:
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cstring>
  5 #include <queue>
  6
  7 using namespace std;
  8
  9 #define INF 0x3f3f3f3f
 10
 11 const int maxn = 1000 + 5;
 12
 13 struct people {
 14     int T, P, VIP, counter_id;
 15 }Customer[maxn];
 16
 17 int main()
 18 {
 19     int n;
 20     scanf("%d", &n);
 21     for(int i = 0; i < n; ++i) {
 22         scanf("%d %d %d", &Customer[i].T, &Customer[i].P, &Customer[i].VIP);
 23         Customer[i].P = min(Customer[i].P, 60);
 24     }
 25
 26     int K, vipK;
 27     scanf("%d %d", &K, &vipK);
 28
 29     bool vis[maxn] = {0};
 30
 31     queue<people> q;
 32
 33     bool ok = true;
 34
 35     for(int i = 0; i < n; ++i) {
 36         if(Customer[i].T > 0)
 37             break;
 38         if(Customer[i].VIP) {
 39             ok = false;
 40             Customer[i].counter_id = vipK;
 41             vis[i] = 1;
 42             q.push(Customer[i]);
 43             break;
 44         }
 45     }
 46
 47     if(ok) {
 48         Customer[0].counter_id = 0;
 49         vis[0] = 1;
 50         q.push(Customer[0]);
 51     }
 52
 53     int sum = 0, _max = 0, last = 0, now = 0;
 54     int windows[15] = {0}, num_windows[15] = {0};
 55
 56     while(!q.empty()) {
 57         _max = max(_max, windows[q.front().counter_id] - q.front().T);
 58         sum += max(0, windows[q.front().counter_id] - q.front().T);
 59         windows[q.front().counter_id] = max(windows[q.front().counter_id], q.front().T) + q.front().P;
 60         last = max(last, windows[q.front().counter_id]);
 61         ++num_windows[q.front().counter_id];
 62
 63         int minn = INF, idx = 0;
 64
 65         for(int i = 0; i < K; ++i) {
 66             if(windows[i] < minn) {
 67                 minn = windows[i];
 68                 idx = i;
 69             }
 70         }
 71
 72         while(now < n && vis[now])
 73             ++now;
 74         if(now == n)
 75             break;
 76
 77         ok = true;
 78
 79         if(Customer[now].T <= windows[idx]) {
 80             ok = true;
 81             if(idx == vipK || windows[idx] == windows[vipK]) {
 82                 for(int i = now; i < n; ++i) {
 83                     if(!vis[i]) {
 84                         if(Customer[i].T > windows[idx]) {
 85                             break;
 86                         }
 87                         if(Customer[i].VIP) {
 88                             ok = false;
 89                             Customer[i].counter_id = vipK;
 90                             q.push(Customer[i]);
 91                             vis[i] = 1;
 92                             break;
 93                         }
 94                     }
 95                 }
 96             }
 97             if(ok) {
 98                 Customer[now].counter_id = idx;
 99                 q.push(Customer[now]);
100                 vis[now] = 1;
101             }
102         }
103         else {
104             if(Customer[now].VIP && windows[vipK] <= Customer[now].T) {
105                 Customer[now].counter_id = vipK;
106                 q.push(Customer[now]);
107                 vis[now] = 1;
108             }
109             else {
110                 for(int i = 0; i < K; ++i) {
111                     if(windows[i] <= Customer[now].T) {
112                         Customer[now].counter_id = i;
113                         q.push(Customer[now]);
114                         vis[now] = 1;
115                         break;
116                     }
117                 }
118             }
119         }
120         q.pop();
121     }
122
123     printf("%.1f %d %d\n", sum * 1.0 / n, _max, last);
124
125     for(int i = 0; i < K; ++i) {
126         printf("%d%c", num_windows[i], i == K - 1 ? ‘\n‘ : ‘ ‘);
127     }
128
129     return 0;
130 }

原文地址:https://www.cnblogs.com/fan-jiaming/p/9757048.html

时间: 2024-10-12 19:45:54

PTA 银行排队问题之单队列多窗口加VIP服务 队列+模拟的相关文章

JS~模拟表单在新窗口打开,避免广告拦截

说起广告拦截,这应该是浏览器的一个特性,它会将window.open产生的窗口默认为一个广告,将它进行拦截,但有时,这不是我们所希望的,有时,我们就是需要它在客户端的浏览器上弹出一个新窗口,以展示数据处理的更新结果,例如,一个创建商品的预览功能,它需要先保存数据,然后再在新窗口展示最新的信息,这种需求并不少,而大多数人的作法就是使用window.open去弹窗口,但它确实不是一种好的方式! 新方式来了 我们知道表单提交实际上可以把POST的结果响应到新窗口上,我们就是利用表单的这种性质,在JS中

基于滑动窗口的免锁队列设计实现

消息队列是一些平台的通信的基石,各个任务的通信基于消息队列,消息队列的处理速度往往影响整个系统的性能,为了避免多任务同时处理消息队列,通常有任务处理队列时需要加锁来互斥访问. 1:假设每个模块有自己的消息队列,任何模块都可以给这个模块发消息,但只有本模块会从消息队列中取消息处理,如下图所示一个消息队列可能多个任务同时写,一个任务读. 2:为了避免多个任务处理时使用锁导致的效率底线我们可以使用免锁设计来实现队列操作,见http://www.cnblogs.com/chencheng/p/35276

队列应用场景,自己实现队列(一)

一.队列使用场景:为什么需要队 在web开发中,我们经常会遇到需要处理批量任务的时候,这些批量任务可能是用户提交的,也可能是当系统被某个事件触发时需要进行批量处理的,面对这样的任务,如果是用户提交的批量任务,初级程序员只能让用户触发提交动作后,等待服务器处理完毕,并且将结果返回到浏览器,期间用户不能关掉浏览器窗口,如果数据比较大,或者处理速度比较慢,那用户体验将会因此受到直接影响.但是当我们使用某讯或者某浪的邮箱时,点击群发邮件之后,只需等待很短的时间,浏览器提示提交成功,正在发送之类的信息时,

队列应用场景,自己实现队列

详见:http://www.ucai.cn/blogdetail/7024?mid=1&f=9 可以在线运行查看效果哦 一.队列使用场景:为什么需要队列 在web开发中,我们经常会遇到需要处理批量任务的时候,这些批量任务可能是用户提交的,也可能是当系统被某个事件触发时需要进行批量处理的,面对这样的任务,如果是用户提交的批量任务,初级程序员只能让用户触发提交动作后,等待服务器处理完毕,并且将结果返回到浏览器,期间用户不能关掉浏览器窗口,如果数据比较大,或者处理速度比较慢,那用户体验将会因此受到直接

队列的应用:双端队列

双端队列(Deque:double ended queue)就是一个两端都是结尾的队列.队列的每一端都可以插入数据项和移除数据项.相对于普通队列,双端队列的入队和出队操作在两端都可进行. 双端队列的示意图: left:左端    right:右端 这里我们使用最常用的顺序结构来存储双端队列,为了节省空间,把它首尾相连,构成循环队列.并且规定left指向左端的第一个元素,right指向右端的下一个位置.那么队空的判断则是left==right,队满是(left-1+MAX)%MAX==right或

C# 消息队列-Microsoft Azure service bus 服务总线

先决条件 Visual Studio 2015或更高版本.本教程中的示例使用Visual Studio 2015. Azure订阅. 注意 要完成本教程,您需要一个Azure帐户.您可以激活MSDN订阅者优惠或注册一个免费帐户. 1.使用Azure门户创建一个命名空间 如果已经创建了Service Bus命名空间,请跳转到使用Azure门户部分创建队列.+ 创建服务命名空间 要在Azure中开始使用服务总线队列,必须首先创建一个命名空间.命名空间提供了一个用于在应用程序中寻址服务总线资源的作用域

队列的实现:链式队列

队列常常也使用链式存储的方式来实现.为了方便操作,同顺序存储一样,我们要维护一个头指针和一个尾指针.如下图: 在链式队列中显然不会出现假溢出的情况.但在出队时,要及时释放内存.由于在队列的实现:顺序队列中,对队列的描述已经很清楚了.就闲话不多说,直接上代码: 类定义和类实现 #include<iostream> #include<iomanip> using namespace std; typedef int ELemType; class QNode //节点类型 { publ

消息队列入门(二)消息队列的开源实现

消息队列入门(二)消息队列的开源实现 关于AMQP AMQP 是 Advanced Message Queuing Protocol,即高级消息队列协议.AMQP不是一个具体的消息队列实现,而 是一个标准化的消息中间件协议.目标是让不同语言,不同系统的应用互相通信,并提供一个简单统一的模型和编程接口.目前主流的ActiveMQ和RabbitMQ都支持AMQP协议. AMQP相关的角色和职责 Producer 消息生产者 一个给exchange发送消息的程序,发送方式大致是:它首先创建一个空消息,

DS队列----银行单队列多窗口模拟

题目描述 假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙.当有窗口空闲时,下一位顾客即去该窗口处理事务.当有多个窗口可选择时,假设顾客总是选择编号最小的窗口. 本题要求输出前来等待服务的N位顾客的平均等待时间.最长等待时间.最后完成时间. 输入 输入第1行给出正整数N(≤),为顾客总人数:随后N行,每行给出一位顾客的到达时间T和事务处理时间P,并且假设输入数据已经按到达时间先后排好了顺序:最后一行给出正整数K(≤),为开设的营业窗口数. 输出 在一行中输出平