题目如下
注释很详细,全在代码中
#include<bits/stdc++.h>
using namespace std;
class Person//个人信息
{
public:
int get_time,last_time,wait_time;//到达时间,持续时间,等待时间
Person(int a,int b):get_time(a),last_time(b),wait_time(0) {}
Person() {}
};
class Windows//窗口信息
{
public:
int id,time;//窗口编号和顾客所用该窗口时间
Windows(int a,int b):id(a),time(b) {}
Windows() {}
friend bool operator <(const Windows& a,const Windows& b)
{
if(a.time==b.time)
return a.id>b.id;
return a.time>b.time;
}
};
int searchfree(bool* arr,int len)//该函数找出空闲窗口并且id是最小的那个;
{
for(int i=0; i<len; i++)
{
if(arr[i])return i;
}
exit(-2);//没找到输入数据有误就退出
return -1;
}
int main()
{
int num1,a,b,num2,time;
cin>>num1;
vector<Person>v;//储存顾客信息
for(int i=0; i<num1; i++)
{
cin>>a>>b;
b = b>60 ? 60 : b ;
v.push_back(Person(a,b));
}
cin>>num2;
int* win_num=new int[num2];//每个窗口接待顾客的数量
bool* isfree=new bool[num2];//判断该窗口是否空闲
for(int i=0; i<num2; i++)
{
win_num[i]=0;
isfree[i]=true;
}
int id=0,curtime=0,cus_id=0;
priority_queue<Windows>QW;//储存每个顾客完成服务的时间点
while(cus_id<num1)//当顾客编号小于今天的顾客数
{
if(QW.empty()||v[cus_id].get_time<QW.top().time)//如果窗口都空闲或者该顾客到达的时间点小于所有窗口完成任务的时间点
{
if(QW.size()<num2)
{
curtime=v[cus_id].get_time;//当前时间来到这个人到达的时间点
id=searchfree(isfree,num2);//找出空闲窗口的编号
//
}
else
{
curtime=QW.top().time;//当前时间来到正在服务的顾客完成服务的时间点
id=QW.top().id;//编号找出队列中最前面的窗口编号,即为最短时间点且编号最小的窗口编号
v[cus_id].wait_time=curtime-v[cus_id].get_time;//该顾客的等待时间即为当前时间点减去他来的时间点
QW.pop();
}
time=curtime+v[cus_id].last_time;//时间点即为当前时间加上这个顾客所需的办理业务的时间
isfree[id]=false;//该窗口不空闲
QW.push(Windows(id,time));//将窗口编号和窗口完成业务的时间点放进优先级队列
win_num[id]++;//该窗口接待顾客数目增加1
cus_id++;//到下一个顾客
}
else
{
isfree[QW.top().id]=true;
curtime=QW.top().time;//当前时间点来到刚刚完成一位顾客的时间点
QW.pop();
}
}
while(!QW.empty())//如果还有正在进行服务的窗口,不断更新当前时间点
{
curtime=QW.top().time;
QW.pop();
}
int Max=-1,sum=0;
for(int i=0; i<num1; i++)
{
Max=max(Max,v[i].wait_time);//找出每个人的最长等待时间
sum+=v[i].wait_time;
}
cout<<setprecision(1)<<fixed<<(double)sum/num1<<" "<<Max<<" "<<curtime<<endl;
for(int i=0; i<num2; i++)
{
if(i==0)
cout<<win_num[i];
else
cout<<" "<<win_num[i];
}
delete[]isfree;
delete[]win_num;
}