您的位置:首页 > 其它

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;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐