7-4 银行排队问题之单队列多窗口加VIP服务 (30 分)
说实话这道题挺恶心 有意思的,大模拟,主要的思路就是模拟时间轴。
题目描述
假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙。当有窗口空闲时,下一位顾客即去该窗口处理事务。当有多个窗口可选择时,假设顾客总是选择编号最小的窗口。
有些银行会给VIP客户以各种优惠服务,例如专门开辟VIP窗口。为了最大限度地利用资源,VIP窗口的服务机制定义为:当队列中没有VIP客户时,该窗口为普通顾客服务;当该窗口空闲并且队列中有VIP客户在等待时,排在最前面的VIP客户享受该窗口的服务。同时,当轮到某VIP客户出列时,若VIP窗口非空,该客户可以选择空闲的普通窗口;否则一定选择VIP窗口。
本题要求输出前来等待服务的N位顾客的平均等待时间、最长等待时间、最后完成时间,并且统计每个窗口服务了多少名顾客。
输入格式:
输入第1行给出正整数N(≤1000),为顾客总人数;随后N行,每行给出一位顾客的到达时间T、事务处理时间P和是否VIP的标志(1是VIP,0则不是),并且假设输入数据已经按到达时间先后排好了顺序;最后一行给出正整数K(≤10)—— 为开设的营业窗口数,以及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
#include <bits/stdc++.h>
struct consumer
{double arrive;double process;double start;double end;double wait;int vip;int skip;
}c[1001];
struct windows
{int count;int availiable;double end;
}w[11];
using namespace std;
int main()
{memset(c,0,sizeof(c));memset(w,0,sizeof(w));int n,k,arrive,process,vip;cin>>n;for (int i=0;i<n;i++){cin>>arrive>>process>>vip;if (process>60) process=60;c[i].arrive=arrive;c[i].process=process;c[i].vip=vip;}int v;cin>>k>>v;for (int i=0;i<k;i++) w[i].availiable=1;int count=0;int m;for (m=0;;m++){if (count==n) break;for (int i=0;i<k;i++) //窗口刷新 {if (w[i].end==m){w[i].availiable=1;}}if (w[v].availiable==1) //vip窗口拉人 {for (int i=0;c[i].arrive<=m&&i<n;i++){if (c[i].skip==1) continue;if (c[i].vip==1){c[i].skip=1;c[i].start=m;c[i].end=c[i].start+c[i].process;c[i].wait=c[i].start-c[i].arrive;w[v].availiable=0;w[v].end=m+c[i].process;count++;w[v].count++;break;}}}for (int i=0;i<k;i++){if (w[i].availiable==1){for (int j=0;j<n&&c[j].arrive<=m;j++){if (c[j].skip==1) continue;c[j].start=m;c[j].end=c[j].start+c[j].process;c[j].skip=1;c[j].wait=c[j].start-c[j].arrive;w[i].availiable=0;w[i].count++;w[i].end=m+c[j].process;count++;break;}}}}double sum=0;int maxwait=-1,last=-1;for (int i=0;i<n;i++){sum+=c[i].wait;if (c[i].wait>maxwait){maxwait=c[i].wait;}if (c[i].end>last){last=c[i].end;}
// printf("*%.1lf %.1lf %.1lf\n",c[i].start,c[i].process,c[i].end);}printf("%.1lf %d %d\n",sum/n,maxwait,last);printf("%d",w[0].count);for (int i=1;i<k;i++){printf(" %d",w[i].count);}return 0;
}