[队列]银行柜台问题

#include<iostream>
#include<stdlib.h>
#include<queue>
template<typename eT>
class node {
public:
	eT data;
	node* next;
	node(const eT& data_, node<eT>* next_ = NULL)
	{
		data = data_;
		next = next_;
	}
	node() : next(NULL) {}
	~node() {}
};
template<typename eT>
class linkQueue :public std::queue<eT> {
public:
	node<eT>* front, *tail;
public:
	linkQueue() { front = tail = NULL; }
	~linkQueue() {
		node<eT>* tmp;
		while (front != NULL) {
			tmp = front;
			front = front->next;
			delete tmp;
		}
	}
	bool isEmpty() { return front == NULL; }
	void enQueue(const eT& x) {
		if (tail == NULL)
			front = tail = new node<eT>(x);
		else {
			tail->next = new node<eT>(x);
			tail = tail->next;
		}
	}
	eT deQueue() {
		node<eT>* tmp = front;
		eT value = front->data;
		front = front->next;
		if (front == NULL) tail = NULL;
		delete tmp;
		return value;
	}
};
template <typename eT>
class priorityQueue :public linkQueue<eT>
{
public:
	void enQueue(const eT& x)
	{
		if (this->tail == NULL)
			this->front = this->tail = new node<eT>(x);
		else {
			node<eT>*p;
			if (x < this->front->data)
			{
				p = new node<eT>(x, this->front); 
                this->front = p;
			}
            else
            {
                p=this->front;
                while(p->next!=NULL&&p->next->data<x)
                    p=p->next;
			if (p->next == NULL)
			{
				this->tail->next = new node<eT>(x);
				this->tail = this->tail->next;
			}
			else p->next = new node<eT>(x, p->next);
		}
        }
		
	}
};
	class simulator {
		int noOfServer;           //柜台个数
		int customNum;				//顾客个数
		int* arrivalTimeList;
		int* serviceTimeList;
		struct eventT      //定义柜台事件的结构体,用来描述事件
		{
			int time; //事件发生时间
			int type; //事件类型。0 为到达,1 为离开
			bool operator<(const eventT& e) const { return time < e.time; }
		};
	public:
		simulator() {
			//std::cout << "请输入柜台数:";
			std::cin >> noOfServer;
			//std::cout << "请输入模拟的顾客数:";
			std::cin >> customNum;
			arrivalTimeList = new int[customNum];
			serviceTimeList = new int[customNum];
			for (int i = 0; i < customNum; i++) {
				std::cin >> arrivalTimeList[i];
			}
			for (int i = 0; i < customNum; i++) {
				std::cin >> serviceTimeList[i];
			}
		}
		~simulator() {
			delete arrivalTimeList;
			delete serviceTimeList;
		}
		int avgWaitTime() {
			int serverBusy = 0;       //正在忙碌的柜台数量
			int serviceTime = 0;    //服务时间
			int currentTime = 0;   //当前时间
			int totalWaitTime = 0;  //总等待时间
			linkQueue<eventT> waitQueue;
			priorityQueue<eventT> customerQueue;
			linkQueue<int> serviceTimeQueue;
			eventT currentEvent;
			//生成初始的事件队列
			int i;
			for (i = 0; i < customNum; ++i)
			{
				currentEvent.type = 0;   //表示柜台事件目前为空
				currentTime = arrivalTimeList[i];//每个顾客的到达时刻
				currentEvent.time = currentTime;
				customerQueue.enQueue(currentEvent);
				serviceTimeQueue.enQueue(serviceTimeList[i]);//每个顾客的服务时间
			}
            i=0;
			while (!customerQueue.isEmpty())
			{
				currentEvent = customerQueue.deQueue();
				currentTime = currentEvent.time;
				switch (currentEvent.type)    //判断顾客离开还是进入柜台
				{
				case 0://顾客离开柜台                                       
					if (serverBusy != noOfServer)               
					{
						++serverBusy;
						currentEvent.time = currentTime + serviceTimeList[i++];
						currentEvent.type = 1;
						customerQueue.enQueue(currentEvent);
					}
					else
						waitQueue.enQueue(currentEvent);
					break;

						
				case 1:
					if (!waitQueue.isEmpty())
					{
						currentEvent = waitQueue.deQueue();
						totalWaitTime += currentTime - currentEvent.time;
						currentEvent.time = currentTime + serviceTimeList[i++];
						currentEvent.type = 1;
						customerQueue.enQueue(currentEvent);
					}
					else --serverBusy;
					}

				}
			
			return totalWaitTime / customNum; //计算平均排队时间
		}
	};
	int main()
	{
		simulator sim;
		std::cout << sim.avgWaitTime() << std::endl;
		return 0;
	}

挺有趣的一道队列题,参考的也是老师课上的思路。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值