
返回目录:
Chilan Yu:《数据结构》目录链接zhuanlan.zhihu.com

【问题描述】
请用顺序队列或链式队列来完成本题。
我们大多都有在银行排队的经历,唉,那坑爹的排队啊!现在就让我们来算算我们这些客户平均需要等多久吧。
每天刚开始时银行会开m个窗口来为我们total个客户办理业务,当有客户需要办理业务时,先选择可以办理业务的窗口,如果有多个窗口可以办理业务就选择空闲时间最长的窗口,如果有多个窗口空闲的时间一样长,则选择序号小的窗口办理业务。假设我们每个人来到的时间和办理业务所需要的时间(为了简化问题,采用整数表示时间)都知道了。现在请你算算我们平均需要等待多久呢?
【输入形式】
有多组测试数据,每组数据开始有两个正整数m(<20)和total(<200),后面有total对整数,对应客户先后到来的时间以及办理业务所需的时间。
【输出形式】
平均等待的时间,保留两位小数。
【样例输入】
2 6 1 3 4 1 5 3 9 2 13 4 13 3
3 14 0 3 2 2 2 4 5 4 7 2 11 3 12 3 12 4 12 1 13 3 15 4 19 1 22 3 23 2
2 5 0 6 0 5 0 6 7 1 7 2
【样例输出】
0.00
0.29
1.20
【提示】
题目中选择办理的窗口有三个状态,实际上从序号自小到大查找可以最早办理业务的窗口就已经满足上述三个状态了。
#include <iostream>
#include <iomanip>
using namespace std;
struct Node{
int data;
Node *succ;
Node(){succ=NULL;};
Node(int d,Node *s=NULL):data(d),succ(s){}
};
class Queue{//队列类
protected:
Node *front, *rear;//头指针,尾指针
int _size;//队列大小
void init(){ rear = front = new Node; _size = 0; }//新开一个结点并且初始化
void clear();//清空队列
public:
Queue(){init();}//构造函数
Queue(const Queue &Q);//复制构造函数
~Queue(){clear();}//析构函数
int outQueue();//出队
int inQueue(const int &e);//入队
int getHead() const;//读取队首结点
bool empty(){return rear==front;}
int size(){return _size;}
int insertQueue(const int& e);//按时间大小插队
};
void Queue::clear(){//清空队列
while(!empty())
outQueue();
}
Queue::Queue(const Queue &Q){//复制构造函数
init();//新开一个结点并且初始化
_size = Q._size;//复制队列大小
for(Node *p=Q.front->succ;p;p=p->succ)//依次复制入队
inQueue(p->data);
}
int Queue::outQueue(){//出队
Node *p = front->succ;
int e = p->data;
front->succ = p->succ;
if(rear==p) rear = front;
delete p;
_size--;
return e;
}
int Queue::inQueue(const int &e){//入队
Node *p = new Node(e);//调用复制构造函数开辟新的结点
rear->succ = p;//新结点连到最后
rear = p;//后移尾指针
_size++;
return e;
}
int Queue::insertQueue(const int &e){//按时间大小插队
Node *p = front;
++_size;
for(;p->succ&&p->succ->data<e;p=p->succ)//按照时间顺序
;
Node *pN = new Node(e);
pN->succ = p->succ;
p->succ = pN;
return e;
}
int Queue::getHead() const{//读取队首结点
return front->succ->data;
}
double waitTime(int m,int total){//计算总的等待时间
Queue window;
int arri=0,stay=0,time=0;//到达时间,等待时间,总等待时间
while(total--){
cin >> arri >> stay;//当前处理人的到达时间和等待时间
while( window.size() && window.getHead()<=arri )//窗口非空,并且队列中第一个离开的人的离开时间小于当前处理人的到达时间
window.outQueue();//把队列中的第一个人出队
if( window.size()<m )//窗口没有满
window.insertQueue(arri+stay);//把当前处理人入队(入队的是离开时间)
else{//窗口满了,需要等待
time += window.getHead()-arri;//累加等待时间
int oldArri = window.getHead();//记录刚才离开的人的离开时间
window.outQueue();//刚才那个人出队
window.insertQueue(oldArri+stay);//处理当前人入队
}
}
return time;
}
int main()
{
int m, total;
while( cin >> m >> total )
cout << fixed << setprecision(2) << waitTime(m,total)/total << endl;
}
#include<bits/stdc++.h>
using namespace std;
int m,tot,a,b;
template<class T> class Pque{
protected:
struct node{
T data;
node* next;
node():next(NULL){}
};
node* head;
int Size;
public:
Pque():Size(0){
head=new node;
}
~Pque(){
head=head->next;
while(head) {
node* t=head;
head=head->next;
delete t;
}
}
void push(T t){
node* p=head;
for(;p->next&&p->next->data<t;p=p->next);
node* n=new node;
n->data=t;n->next=p->next;p->next=n;
++Size;
}
T pop(){
node* p=head->next;
head->next=p->next;
T t=p->data;
delete p;--Size;
return t;
}
T front(){return head->next->data;}
int size(){return Size;}
};
int main(){
while(cin>>m){
Pque<int> win;cin>>tot;
double wt=0;
for(int i=0;i<tot;++i){
cin>>a>>b;
while(win.size()&&win.front()<=a)win.pop();
if(win.size()<m) win.push(a+b);
else{
int k=win.front();
wt+=k-a;
win.pop();
win.push(k+b);
}
}
cout<<fixed<<setprecision(2)<<wt/tot<<endl;
}
}
返回目录:
Chilan Yu:《数据结构》目录链接zhuanlan.zhihu.com
