队列的应用-银行排队程序模拟
- 格式:doc
- 大小:251.50 KB
- 文档页数:3
队列的应用:单服务台排队系统的模拟一、三个模拟1.离散事件模拟系统在排队系统中,主要有两类事件:顾客的到达事件和服务完毕后顾客的离去事件,整个系统就是不断有到达事件和离开事件的发生,这些事件并不是连续发生的,因此这样的系统被称为离散事件模拟系统。
(1)事件处理过程如果服务员没空,就去队列中排队;否则就为这个顾客生成服务所需的时间t,表示服务员开始为它服务,所需的服务时间是t。
每当一个离开事件发生,就检查有没有顾客在排队,如果有顾客在排队,则让队头顾客离队,为它提供服务,如果没有顾客排队,则服务员可以休息。
(2)如何产生顾客到达事件和离开事件在一个排队系统中,顾客的到达时间和为每个顾客服务的时间并不一定是固定的。
但从统计上来看是服从一定的概率分布。
假设到达的间隔时间和服务时间都满足均匀分布,则可以用随机数产生器产生的随机数。
①以生成顾客到达事件为例子如顾客到达的间隔时间服从[a,b]之间的均匀分布,则可以生成一个[a,b]之间的随机数x,表示前一个顾客到达后,经过了x的时间后又有一个顾客到达。
[a,b]之间的随机数可以按照下面的过程产生:假如系统的随机数生成器生成的随机数是均匀分布在0到RAND_MAX之间,可以把0到RAND_MAX之间的区间等分成b-a+1个,当生成的随机数落在第一个区间,则表示生成的是a,当落在第二个区间,则表示生成的是a+1…当落在最后一个区间,则表示生成的是b。
这个转换可以用rand()*(b-a+1)/( RAND_MAX+1)+a实现,rand 表示系统的随机数生成函数。
2.离散的时间驱动模拟在得到了在x秒后有一个事件生成的信息时,并不真正需要让系统等待x秒再处理该事件。
在模拟系统中,一般不需要使用真实的精确事件,只要用一个时间单位即可,这个时间单位是嘀嗒tick,可以表示1秒,也可以表示1min\1h.沿着时间轴,模拟每一个嘀嗒中发生了什么事件并处理该事件。
模拟开始时时钟是0嘀嗒,随后每一步都把时钟加1嘀嗒,并检查这个时间内是否有事件发生,如果有,则处理并生成统计信息。
循环队列-----银⾏排号叫号系统模仿运⽤知识:循环队列的顺序存储下⾯是⽂件运⾏成功的样式展⽰1 #include<stdio.h>2 #include<stdlib.h>3#define FALSE 04#define ERROR 05#define OK 16#define TRUE 17#define MAXSIZE 6 //队列的长度8 typedef int Elem;9 typedef int Status;10/*11这⾥似乎没⽤到GetHead(),QueueEmpty()这两个函数,但是我还是定义了12*/13//队列的顺序存储结构14 typedef struct15 {16 Elem data[MAXSIZE];17int front;18int rear;19 }Sq;2021int IsInit = FALSE;//这个是⽤来判断是否初始化,即主函数中⽤来要求先输⼊0(即先选上班,不然队列没有初始化);22//队列的初始化,即将队列的头尾指针都等于0;23void Init(Sq &S)24 {25 S.front = 0;26 S.rear = 0;27 IsInit = TRUE;28 }29//⼊队列,注:⼊队列时会空出⼀个数组位置,⽅便尾指针的指向,所以这也是判断队满时为什么尾指针要加130 Status EnQueue(Sq &S,Elem num)31 {32if((S.rear+1)%MAXSIZE==S.front) return ERROR;//判断是否栈满,即尾指针后移⼀位与头指针相逢,队列就满了33 S.data[S.rear] = num; //存数34 S.rear = (S.rear+1)%MAXSIZE; //队尾指针后移35return OK;36 }37//出队列38 Status DeQueue(Sq &S,Elem &e)39 {40if(S.front == S.rear) return ERROR;//判断队空,当队头指针遇到队尾指针,队空41 e = S.data[S.front]; //队头元素赋值给e42 S.front = (S.front+1)%MAXSIZE;//队头指针后移43return OK;44 }45//获得队列的长度46int getLen(Sq S)47 {48return (S.rear+MAXSIZE-S.front)%MAXSIZE;//返回队列的长度49 }50//获得队列的头元素51 Status GetHead(Sq S,Elem &e)52 {53if(S.rear == S.front)54return ERROR;55else{56 e = S.data[S.front];57return OK;58 }59 }60//判断队空61 Status QueueEmpty(Sq S)62 {63if(S.front==S.rear) return ERROR;64else65return OK;66 }67//判断队满68 Status QueueFull(Sq S)69 {70if((S.rear+1)%MAXSIZE==S.front)71return ERROR;72else73return OK;74 }75int main()76 {77 Sq S;78int n,num=0;79 Elem e;8081while(1)82 {83 printf("---------------银⾏叫号系统-----------\n");84 printf("--------------------------------------\n");85 printf("1.上班\n");86 printf("2.排号\n");87 printf("3.叫号\n");88 printf("0.下班\n");89 printf("---------------------------------------\n\n");9091 scanf("%d",&n);92switch(n)93 {94case0:if(!IsInit)95 {96 printf("要先开始上班才能下班哦!!\n\n");97break;98//为什么要有这个判断呢,因为队列要初始化,这⾥其实可以不做判断 99 }100if(!QueueEmpty(S))101 {102 printf("下班啦,可以回家了\n\n");103return0;104 }else105 {106 printf("还有业务没有完成,暂时不能下班!!\n\n");107break;108 }109case1:110 Init(S);111 num = 0;112 printf("⼀切准备就绪,开始上班\n\n");113break;114115case2:116if(!IsInit)117 {118 printf("要先开始上班,请做好⼯作准备!!\n\n");119break;120//为什么要有这个判断呢,因为队列要初始化121 }122if(QueueFull(S))123 {124//如果队列没满,就⼊队列125 EnQueue(S,++num);126 printf("当前是%d号,前⾯有%d位\n\n",num,getLen(S)-1);127break;128 }else129 {130//如果队列满了131 printf("⼈已满了!!请耐⼼等待\n\n");132break;133 }134case3:135if(!IsInit)136 {137 printf("新的⼀天开始了\n要先开始上班,请先做好准备!!\n\n");138break;139//为什么要有这个判断呢,因为队列要初始化140 }141if(DeQueue(S,e))142 {143//如果队列没空,就可以出队列144 printf("%d号业务办理成功!还有%d⼈在等待!\n\n",e,getLen(S));145break;146 }else147 {148//如果队列空了149 printf("当前没有⼈办理业务!!\n\n");150break;151 }152default :153 printf("⽆效操作请重新输⼊\n\n");154break;155156 } 157 } 158 }。
优先级队列银行排队问题c语言编写下载提示:该文档是本店铺精心编制而成的,希望大家下载后,能够帮助大家解决实际问题。
文档下载后可定制修改,请根据实际需要进行调整和使用,谢谢!本店铺为大家提供各种类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by this editor. I hope that after you download it, it can help you solve practical problems. The document can be customized and modified after downloading, please adjust and use it according to actual needs, thank you! In addition, this shop provides you with various types of practical materials, such as educational essays, diary appreciation, sentence excerpts, ancient poems, classic articles, topic composition, work summary, word parsing, copy excerpts, other materials and so on, want to know different data formats and writing methods, please pay attention!优先级队列银行排队问题C语言编写1. 引言在银行等服务行业,客户经常需要排队等待服务。
攻坚实验三银行业务队列简单模拟
一、实验目的
熟练掌握队列的基本操作,理解队列的应用。
二、实验内容
设某银行有A、B两个业务窗口,且处理业务的速度不一样,其中A窗口处理速度是B窗口的2倍---即当A窗口处理完2个顾客时,B窗口处理完一个顾客。
给定到达银行的顾客序列,请按业务完成的顺序输出顾客序列。
假定不考虑顾客先后到达的时间间隔,并且当不同窗口同时处理完2个顾客时,A窗口顾客优先输出。
三、实验要求
1. 输入说明:输入为一行正整数,其中第1个数字N(N<=1000)为顾客总数,后面跟着N位顾客的编号。
编号为奇数的顾客需要到A窗口办理业务,为偶数的顾客则去B窗口。
数字间以空格分隔。
2.输出说明:按业务处理完成的顺序输出顾客的编号。
数字间以空格分隔,但最后一个编号后不能有多余的空格。
四、实验分析
(1)问题分析
首先需要针对A和B业务设计两个循环队列,分别处理两类业务请求;然后根据输入序列整数的奇偶性将各个整数分配到这两个队列中。
另外,需要设计针对两个队列处理过程的流程,这是一个循环。
在循环中,先从A队列中输出两个元素,然后再从B队列中输出一个元素。
当发现某一个队列中的元素为空时,输出另一个队列中的所有元素。
(2)实现要点
采用统一的循环队列函数处理两个队列的操作:注意对队列满、空情况的
判断。
五、主要仪器及耗材
计算机及VC6软件六、实验参考代码。
(原创)7-1银⾏业务队列简单模拟(30分)设某银⾏有A、B两个业务窗⼝,且处理业务的速度不⼀样,其中A窗⼝处理速度是B窗⼝的2倍 —— 即当A窗⼝每处理完2个顾客时,B窗⼝处理完1个顾客。
给定到达银⾏的顾客序列,请按业务完成的顺序输出顾客序列。
假定不考虑顾客先后到达的时间间隔,并且当不同窗⼝同时处理完2个顾客时,A窗⼝顾客优先输出。
输⼊格式:输⼊为⼀⾏正整数,其中第1个数字N(≤1000)为顾客总数,后⾯跟着N位顾客的编号。
编号为奇数的顾客需要到A窗⼝办理业务,为偶数的顾客则去B窗⼝。
数字间以空格分隔。
输出格式:按业务处理完成的顺序输出顾客的编号。
数字间以空格分隔,但最后⼀个编号后不能有多余的空格。
输⼊样例:8 2 1 3 9 4 11 13 15输出样例:1 32 9 11 4 13 15解题思路:这道题的意思就是模拟队列,将偶数的数字存到b窗⼝,将奇数的数字存到a窗⼝,⽽且是先进先出,所以可以采⽤队列,将偶数的放在b队列,将奇数的放在a队列;然后每输出两个a队列中的元素再输出⼀个b队列中的元素;还有注意的⼀个点就是,最后是a队列中的元素结尾还是b队列中的元素结尾,这个要分情况讨论;主要是最后空格的规范问题;解法⼀:模拟队列代码如下:1 #include<iostream>2using namespace std;3456struct queue{7int data[1005]; //⽤于存队列的数据;8int tail; //⽤来记录从尾部插⼊了多少个元素;9int head; //计数队头,⽅便取出队头的元素;10 };1112void push(queue *q ,int tmp ) //实现队列的push⽤法;传⼊类型为 queue 的指针 q;传⼊要⼊队的数tmp;13 {14 q->tail ++; //每⼊队⼀个元素,尾部计数器+1;15 q->data[q->tail] = tmp; //将元素⼊队;16 }1718int pop(queue *q) //取出队列的数字,从前端取出;此时要利⽤head记数;19 {20 q->head++; //每取⼀个,就将head+1,记数;21return q->data[q->head]; //返回队头的元素;22 }2324void init(queue *q) //初始化;25 {26 q->tail = -1 ; //将尾和头记数均初始化为-1;27 q->head = -1;28 }2930int notEmpty(queue *q) //判断队列是否为空;31 {32int i ;33if(q->tail == q->head) //如果尾和头的记数⼀样,则队列为空;34 {35 i = 0;36 }37else38 i = 1;39return i; //判断队列不为空;40 }41int counta = 0,countb = 0; //⽤counta 记录⼊a队列的个数;⽤countb 记录⼊b队列的个数;42int main()43 {44 queue a ; //定义,实例化a;45 queue b; //定义,实例化b;46 init(&a); //初始化a队列,并要⽤引⽤符号;47 init(&b); //初始化b队列,并⽤引⽤符号;48int n ;49int c;50 cin>>n;51for(int i = 0 ; i < n ; i++)52 {53 cin>>c;54if(c%2==0)55 {56 push(&b,c); //如果是偶数,则进b队列;57 countb++; //countb相应+1;58 }59else60 {61 push(&a,c); //如果是奇数,则进a队列;62 counta++; //counta相应+1;63 }6465 }66//分情况,注意最后到底是a队列的数结尾还是b队列的数结尾,这影响格式;67if(counta > countb *2) //counta⼤于两倍countb,是a队列的元素结尾,则a最后⼀个元素后⾯不能加空格;68 {69while(notEmpty(&a)||notEmpty(&b)) //当a队列不空或者b队列不空时;70 {71if(notEmpty(&a)) //a队列不空;72 {73 cout<<pop(&a);74 counta--;75if(counta != 0)76 cout<<"";77 cout<<pop(&a); //输出两个a队列的元素;注意这⾥a最后⼀个元素后⾯不能加空格;78 counta--;79if(counta != 0)80 cout<<"";81 }82if(notEmpty(&b))83 {84 cout<<pop(&b); //输出⼀个b队列的元素;85 cout<<"";86 }87 }88 }89else90if(counta <= countb *2) //counta⼩于等于两倍countb,是b队列的元素结尾,则b最后⼀个元素后⾯不能加空格;91 {92while(notEmpty(&a)||notEmpty(&b))93 {94if(notEmpty(&a))95 {96 cout<<pop(&a); //输出两个a队列的元素;97 cout<<"";98 cout<<pop(&a);99 cout<<"";100 }101if(notEmpty(&b))102 {103 cout<<pop(&b); //输出⼀个b队列的元素,注意b队列最后⼀个元素的后⾯不能加空格;104 countb--;105if(countb != 0)106 {107 cout<<"";108 }109110 }111 }112 }113114115116return0;117 }解法⼆:直接⽤stl中的queue;1 #include<iostream>2 #include<queue> //队列头⽂件3using namespace std;456long long int b[10005];7 queue<int>qa; //定义⼀个qa队列,⽤于存放奇数8 queue<int>qb; //定义⼀个qb队列,⽤于存放偶数;9int tmp1; //⽤于取出qa“每次最前” 的元素;10int tmp2; //⽤于取出qa“每次最前” 的元素;11int n ;12int main()13 {14 cin>>n;15for(int i = 0 ; i < n ; i++)16 {17 cin>>b[i];18if(b[i]%2==0)19 qb.push(b[i]); //如果为偶数,则放⼊qb队列;20else21 qa.push(b[i]); //如果为奇数,则放⼊qa队列;22 }2324int counta = qa.size(); //⽤counta 记录qa队列的长度;25int countb = qb.size(); //⽤countb 记录qb队列的长度;26//分情况,注意最后到底是qa队列的数结尾还是qb队列的数结尾,这影响格式;27if(counta > countb *2) //counta⼤于两倍countb,是qa队列的元素结尾,则a最后⼀个元素后⾯不能加空格;28 {29while(!qa.empty()||!qb.empty()) //当qa队列不空或者qb队列不空时;30 {31if(!qa.empty()) //a队列不空;32 {33 tmp1 = qa.front(); //取出qa 队头的元素;34 cout<<tmp1; //输出qa队头的元素;35 qa.pop(); //将qa队头的元素去掉;36 counta--; //qa长度-1;37if(counta != 0) //注意这⾥a最后⼀个元素后⾯不能加空格;38 cout<<"";39 tmp1 = qa.front(); //再进⾏⼀遍上⾯的操作;40 cout<<tmp1;41 qa.pop();42 counta--;43if(counta != 0)44 cout<<"";45 }46if(!qb.empty())47 {48 tmp2 = qb.front(); //取出qb 队头的元素;49 cout<<tmp2; //输出qb队头的元素;50 qb.pop(); //将qb队头的元素去掉;51 cout<<"";52 }53 }54 }55else56if(counta <= countb *2) //counta⼩于等于两倍countb,是b队列的元素结尾,则b最后⼀个元素后⾯不能加空格;57 {58while(!qa.empty()||!qb.empty()) //当qa队列不空或者qb队列不空时;59 {60if(!qa.empty()) //qa队列不空时;61 {62 tmp1 = qa.front(); //与上⾯的if类似,只是不需要注意尾部是否输出空格;63 cout<<tmp1;64 qa.pop();65 cout<<"";66 tmp1 = qa.front();67 cout<<tmp1;68 qa.pop();69 cout<<"";70 }71if(!qb.empty())72 {73 tmp2 = qb.front(); //与上⾯的if类似,需要注意尾部是否输出空格;74 cout<<tmp2;75 qb.pop();76 countb--;77if(countb != 0)78 {79 cout<<"";80 }8182 }83 }84 }858687return0;88 }。
用队列解决银行排队叫号软件的编程一.实验目的掌握队列的逻辑结构及顺序存储结构和链式存储结构。
熟练运用C语言实现队列的基础操作。
灵活运用队列解决实际问题。
二.实验内容用队列解决银行排队叫号软件的编程,主要要求如下:程序运行后,当看到“请点击触摸屏获取号码:”的提示时,只要按任意键,即可显示“您的号码是:xxx,你的前面有YYY位”的提示,其中xxx是所获得的服务号码,YYY是在xxx之前来的正在等待服务的人数。
用多线程技术模拟服务窗口(可模拟多个),具有服务员工呼叫顾客的行为,假设每个顾客服务的时间是10000ms,时间到后,显示“请xxx号到ZZZ号窗口!”的提示。
其中ZZZ是即将为客户服务的窗口号。
三.实验代码IQueue接口代码:using System;namespace QueueDs{interface IQueue<T>{void EnQueue(T elem); //入队列操作T DeQueue(); //出队列操作T GetFront(); //取对头元素int GetLength(); //求队列的长度bool IsEmpty(); //判断队列是否为空void Clear(); //清空队列bool IsFull();//判断是否为满,在顺序队列中实现该算法,在链式队列中代码实现为空}}IBankQueue接口代码:using System;namespace QueueDs{interface IBankQueue:IQueue<int>{int GetCallnumber();//获得服务号码}}顺序队列代码:using System;namespace QueueDs{publicclass CSeqQueue<T>:IQueue<T>{privateint maxsize; //循环顺序队列的容量private T[] data; //数组,用于存储循环顺序队列中的数据元素privateint front; //指示最近一个己经离开队列的元素所占的位置privateint rear; //指示最近一个进行入队列的元素的位置//索引器public T this[int index]{get{return data[index];}set{data[index] = value;}}//容量属性publicint Maxsize{get{return maxsize;}set{maxsize = value;}}//队头指示器属性publicint Front{get{return front;}set{front = value;}}//队尾指示器属性publicint Rear{get{return rear;}set{rear = value;}}//初始化队列public CSeqQueue() { }public CSeqQueue(int size){data = new T[size];maxsize = size;front = rear = -1;}//入队操作publicvoid EnQueue(T elem){if (IsFull()){Console.WriteLine("Queue is full"); return;}rear=(rear + 1) % maxsize; ; data[rear] = elem;}//出队操作public T DeQueue(){if (IsEmpty()){Console.WriteLine("Queue is empty"); returndefault(T);}front = (front + 1) % maxsize;return data[front];}//获取队头数据元素public T GetFront(){if (IsEmpty()){Console.WriteLine("Queue is empty!");returndefault(T);}return data[(front+1)%maxsize];}//求循环顺序队列的长度publicint GetLength(){return (rear - front + maxsize) % maxsize;}//判断循环顺序队列是否为满publicbool IsFull(){if((front == -1 && rear == maxsize - 1) || (rear + 1) % maxsize == front) {returntrue;}else{returnfalse;}}//清空循环顺序队列publicvoid Clear(){front = rear = -1;}//判断循环顺序队列是否为空publicbool IsEmpty(){if (front == rear){returntrue;}elsereturnfalse;}}}}银行顺序队列代码:using System;using System.Threading;namespace QueueDs{//银行叫号顺序队列类class CSeqBankQueue:CSeqQueue<int>,IBankQueue{privateint callnumber;//记录系统自动产生的新来顾客的服务号//叫号属性publicint Callnumber{get{return callnumber;}set{callnumber = value;}}public CSeqBankQueue (){}public CSeqBankQueue(int size):base(size){}//获得服务号码publicint GetCallnumber(){if ((IsEmpty()) && callnumber == 0)callnumber = 1;elsecallnumber++;return callnumber;}}//服务窗口类class ServiceWindow{IBankQueue bankQ;public IBankQueue BankQget{return bankQ;}set{bankQ = value;}}publicvoid Service(){while (true){Thread.Sleep(10000);if (!bankQ.IsEmpty()){Console.WriteLine();lock (bankQ){Console.WriteLine("请{0}号到{1}号窗口!", bankQ.DeQueue(), );}}}}}}编写银行排队叫号软件主程序class BankQueueApp{publicstaticvoid Main(){IBankQueue bankQueue=null;Console.Write("请选择存储结构的类型:1.顺序队列 2.链队列:"); char seleflag = Convert.ToChar(Console.ReadLine());switch (seleflag){/*初始化顺序队列*/case'1':int count;//接受循环顺序队列的容量Console.Write("请输入队列可容纳人数:");count = Convert.ToInt32(Console.ReadLine());bankQueue = new CSeqBankQueue(count);break;/*初始化链队列*/case'2':bankQueue = new LinkBankQueue();break;}int windowcount =3;//设置银行柜台的服务窗口数。
队列一.实验目的1.理解队列的存储表示和实现;2.掌握队列的各种操作的程序实现;二.实验要求1.认真阅读本实验指导,理解实验内容的具体要求;2.根据教材给出的伪代码,结合实验内容的要求,上机之前编写实验程序;3.上机实验时将实验程序调试运行,输入所给出测试数据后输出结果;4.课后完成实验报告。
三.实验内容1.理解并调试运行下面的参考源程序。
2.利用队列模拟服务台前的排队现象问题。
【问题描述】某银行有一个客户办理业务站,在单位时间内随机地有客户到达,设每位客户的业务办理时间是某个范围内的随机值。
设只有一个窗口,一位业务人员,要求程序模拟统计在设定时间内,业务人员的总空闲时间和客户的平均等待时间。
假定模拟数据已按客户到达的先后顺序依次存于某个正文数据文件中。
对应每位客户有两个数据,到达时间和需要办理业务的时间。
四.参考源程序#include<ctype.h>#include<malloc.h> /* malloc()等*/#include<stdio.h>#include<stdlib.h>#include<process.h> /* exit() */#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define OVERFLOW -2typedef int Status; /* Status 是函数的类型,其值是函数结果状态代码,如OK 等*/ typedef int Boolean; /* Boolean 是布尔类型,其值是TRUE 或FALSE */typedef int QElemType;/*单链队列--队列的链式存储结构*/typedef struct QNode{QElemType data;struct QNode *next;}QNode,*QueuePtr;typedef struct{QueuePtr front,rear; /* 队头、队尾指针*/}LinkQueue;/* 链队列的基本操作(9 个) */void InitQueue(LinkQueue *Q){ /* 构造一个空队列Q */(*Q).front=(*Q).rear=(QueuePtr)malloc(sizeof(QNode)); if(!(*Q).front)exit(OVERFLOW);(*Q).front->next=NULL;}void DestroyQueue(LinkQueue *Q){ /* 销毁队列Q(无论空否均可) */while((*Q).front){(*Q).rear=(*Q).front->next;free((*Q).front);(*Q).front=(*Q).rear;}}void ClearQueue(LinkQueue *Q){ /* 将Q 清为空队列*/QueuePtr p,q;(*Q).rear=(*Q).front;p=(*Q).front->next;(*Q).front->next=NULL;while(p){q=p;p=p->next;free(q);}}Status QueueEmpty(LinkQueue Q){ /* 若Q 为空队列,则返回TRUE,否则返回FALSE */ if(Q.front->next==NULL)return TRUE;elsereturn FALSE;}int QueueLength(LinkQueue Q){ /* 求队列的长度*/int i=0;QueuePtr p;p=Q.front;while(Q.rear!=p){i++;p=p->next;}return i;}Status GetHead_Q(LinkQueue Q,QElemType *e) /* 避免与bo2-6.c 重名*/{ /* 若队列不空,则用e 返回Q 的队头元素,并返回OK,否则返回ERROR */ QueuePtr p;if(Q.front==Q.rear)return ERROR;p=Q.front->next;*e=p->data;return OK;}void EnQueue(LinkQueue *Q,QElemType e){ /* 插入元素e 为Q 的新的队尾元素*/QueuePtr p=(QueuePtr)malloc(sizeof(QNode));if(!p) /* 存储分配失败*/exit(OVERFLOW);p->data=e;p->next=NULL;(*Q).rear->next=p;(*Q).rear=p;}Status DeQueue(LinkQueue *Q,QElemType *e){ /* 若队列不空,删除Q 的队头元素,用e 返回其值,并返回OK,否则返回ERROR */QueuePtr p;if((*Q).front==(*Q).rear)return ERROR;p=(*Q).front->next;*e=p->data;(*Q).front->next=p->next;if((*Q).rear==p)(*Q).rear=(*Q).front;free(p);return OK;}void QueueTraverse(LinkQueue Q,void(*vi)(QElemType)){ /* 从队头到队尾依次对队列Q 中每个元素调用函数vi() */QueuePtr p;p=Q.front->next;while(p){vi(p->data);p=p->next;}printf("\n");}void print(QElemType i){printf("%d ",i);}void main(){int i;QElemType d;LinkQueue q;InitQueue(&q);printf("成功地构造了一个空队列!\n");printf("是否空队列?%d(1:空0:否) ",QueueEmpty(q));printf("队列的长度为%d\n",QueueLength(q));EnQueue(&q,-5);EnQueue(&q,5);EnQueue(&q,10);printf("插入3 个元素(-5,5,10)后,队列的长度为%d\n",QueueLength(q)); printf("是否空队列?%d(1:空0:否) ",QueueEmpty(q));printf("队列的元素依次为:");QueueTraverse(q,print);i=GetHead_Q(q,&d);if(i==OK)printf("队头元素是:%d\n",d);DeQueue(&q,&d);printf("删除了队头元素%d\n",d);i=GetHead_Q(q,&d);if(i==OK)printf("新的队头元素是:%d\n",d);ClearQueue(&q);printf(" 清空队列后,q.front=%u q.rear=%uq.front->next=%u\n",q.front,q.rear,q.front->next);DestroyQueue(&q);printf("销毁队列后,q.front=%u q.rear=%u\n",q.front, q.rear);}。
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个空格分隔,⾏末不能有多余空格。
输⼊样例:100 20 00 20 01 68 11 12 12 15 02 10 03 15 110 12 130 15 062 5 13 1输出样例:15.1 35 674 5 1调了整整⼀下午,真的恶⼼,注意看清加粗字体的要求,⽤队列模拟就⾏了,因为之前⽤结构体写过好⼏次队列了,这次就偷懒直接⽤STL⾥的了,代码如下(因为⽹上代码多是⽤时间流逝模拟,所以贴出我的代码以供交流学习,还望不要抄袭作业1 #include <iostream>2 #include <cstdio>3 #include <algorithm>4 #include <cstring>5 #include <queue>67using namespace std;89#define INF 0x3f3f3f3f1011const int maxn = 1000 + 5;1213struct people {14int T, P, VIP, counter_id;15 }Customer[maxn];1617int main()18 {19int n;20 scanf("%d", &n);21for(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 }2526int K, vipK;27 scanf("%d %d", &K, &vipK);2829bool vis[maxn] = {0};3031 queue<people> q;3233bool ok = true;3435for(int i = 0; i < n; ++i) {36if(Customer[i].T > 0)37break;38if(Customer[i].VIP) {39 ok = false;40 Customer[i].counter_id = vipK;41 vis[i] = 1;42 q.push(Customer[i]);43break;44 }45 }4647if(ok) {48 Customer[0].counter_id = 0;49 vis[0] = 1;50 q.push(Customer[0]);51 }5253int sum = 0, _max = 0, last = 0, now = 0;54int windows[15] = {0}, num_windows[15] = {0};5556while(!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];6263int minn = INF, idx = 0;6465for(int i = 0; i < K; ++i) {66if(windows[i] < minn) {67 minn = windows[i];68 idx = i;69 }70 }7172while(now < n && vis[now])73 ++now;74if(now == n)75break;7677 ok = true;7879if(Customer[now].T <= windows[idx]) {80 ok = true;81if(idx == vipK || windows[idx] == windows[vipK]) {82for(int i = now; i < n; ++i) {83if(!vis[i]) {84if(Customer[i].T > windows[idx]) {85break;86 }87if(Customer[i].VIP) {88 ok = false;89 Customer[i].counter_id = vipK;90 q.push(Customer[i]);91 vis[i] = 1;92break;93 }94 }95 }96 }97if(ok) {98 Customer[now].counter_id = idx;99 q.push(Customer[now]);100 vis[now] = 1;101 }102 }103else {104if(Customer[now].VIP && windows[vipK] <= Customer[now].T) { 105 Customer[now].counter_id = vipK;106 q.push(Customer[now]);107 vis[now] = 1;108 }109else {110for(int i = 0; i < K; ++i) {111if(windows[i] <= Customer[now].T) {112 Customer[now].counter_id = i;113 q.push(Customer[now]);114 vis[now] = 1;115break;116 }117 }118 }119 }120 q.pop();121 }122123 printf("%.1f %d %d\n", sum * 1.0 / n, _max, last);124125for(int i = 0; i < K; ++i) {126 printf("%d%c", num_windows[i], i == K - 1 ? '\n' : '');127 }128129return0;130 }。