PTA 银行排队问题之单队列多窗口加VIP服务 队列+模拟
2018-10-08 20:46
6208 查看
假设银行有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里的了,代码如下(因为网上代码多是用时间流逝模拟,所以贴出我的代码以供交流学习,还望不要抄袭作业,毕竟可能会查重的:[/code]
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <queue> using namespace std; #define INF 0x3f3f3f3f const int maxn = 1000 + 5; struct people { int T, P, VIP, counter_id; }Customer[maxn]; int main() { int n; scanf("%d", &n); for(int i = 0; i < n; ++i) { scanf("%d %d %d", &Customer[i].T, &Customer[i].P, &Customer[i].VIP); Customer[i].P = min(Customer[i].P, 60); } int K, vipK; scanf("%d %d", &K, &vipK); bool vis[maxn] = {0}; queue<people> q; bool ok = true; for(int i = 0; i < n; ++i) { if(Customer[i].T > 0) break; if(Customer[i].VIP) { ok = false; Customer[i].counter_id = vipK; vis[i] = 1; q.push(Customer[i]); break; } } if(ok) { Customer[0].counter_id = 0; vis[0] = 1; q.push(Customer[0]); } int sum = 0, _max = 0, last = 0, now = 0; int windows[15] = {0}, num_windows[15] = {0}; while(!q.empty()) { _max = max(_max, windows[q.front().counter_id] - q.front().T); sum += max(0, windows[q.front().counter_id] - q.front().T); windows[q.front().counter_id] = max(windows[q.front().counter_id], q.front().T) + q.front().P; last = max(last, windows[q.front().counter_id]); ++num_windows[q.front().counter_id]; int minn = INF, idx = 0; for(int i = 0; i < K; ++i) { if(windows[i] < minn) { minn = windows[i]; idx = i; } } while(now < n && vis[now]) ++now; if(now == n) break; ok = true; if(Customer[now].T <= windows[idx]) { ok = true; if(idx == vipK || windows[idx] == windows[vipK]) { for(int i = now; i < n; ++i) { if(!vis[i]) { if(Customer[i].T > windows[idx]) { break; } if(Customer[i].VIP) { ok = false; Customer[i].counter_id = vipK; q.push(Customer[i]); vis[i] = 1; break; } } } } if(ok) { Customer[now].counter_id = idx; q.push(Customer[now]); vis[now] = 1; } } else { if(Customer[now].VIP && windows[vipK] <= Customer[now].T) { Customer[now].counter_id = vipK; q.push(Customer[now]); vis[now] = 1; } else { for(int i = 0; i < K; ++i) { if(windows[i] <= Customer[now].T) { Customer[now].counter_id = i; q.push(Customer[now]); vis[now] = 1; break; } } } } q.pop(); } printf("%.1f %d %d\n", sum * 1.0 / n, _max, last); for(int i = 0; i < K; ++i) { printf("%d%c", num_windows[i], i == K - 1 ? '\n' : ' '); } return 0; }
相关文章推荐
- PTA 7-1 银行排队问题之单队列多窗口服务(25 分)25分代码 (小模拟)
- 银行排队问题之单队列多窗口加VIP服务--PTA数据与结构
- PTA 银行排队问题之单队列多窗口服务
- PTA 7-6(队列) 银行排队问题之单队列多窗口加VIP服务(30 分) 30分代码 大模拟
- PTA 7-5 银行排队问题之单队列多窗口服务
- 数据结构课设 银行排队问题之单队列多窗口服务
- 银行排队问题之单队列多窗口服务
- 习题8.1 银行排队问题之单队列多窗口服务
- 天梯赛 银行排队问题之单队列多窗口服务 (25分)
- PTA 7-4(队列) 银行排队问题之单窗口“夹塞”版(30 分) 30分代码
- PTA 7-6(队列) 银行排队问题之单队列多窗口加VIP服务(30 分) 30分代码
- 统计工龄 模拟EXCEL排序 银行排队问题之单队列多窗口问题 银行业务队列简单模拟 堆栈操作合法性 两个有序序列的中位数
- 7-1 银行排队问题之单队列多窗口服务(25 分)
- PAT 银行排队问题之单窗口“夹塞”版 (队列+模拟) -- 解题报告
- 4 银行排队问题之单队列多窗口加VIP服务 (30分)----模拟
- PintiA 银行排队问题之单队列多窗口服务(25 分)栈与队列
- 银行排队问题之单队列多窗口服务
- PTA 7-6 银行排队问题之单队列多窗口加VIP服务
- 队列应用银行排队问题模拟:计算客户的平均停留时间和等待时间以及每个客户的时间信息,两种方法实现
- 用队列模拟服务台前的排队现象问题_c/c++