1017 Queueing at Bank 测试点3、4 未解决
错误点
测试点3、4过不了,代码写的太乱了,短时间找不出错误的地方,日后再改
代码
#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
#include <string>
#include <algorithm>
#include <iomanip>
using namespace std;
//首先需要对每个顾客,按照到达的时间进行升序排序
//排序后,前m个直接进队列
//后来的,需要在每个队列的对首元素中找最小值
//最小值出列,其他队列减去这个最小值
//其他队列减去该值后,若为0,也需要出列
//后来的,首先需要判断有没有不满的队列
//如果来了一个顾客,先检查所有队列,如果来的顾客的到达时间大于之前的顾客的结束时间,则前一个顾客出队,来的顾客直接进队
struct pair2{
string first;
int second;
};
float to_min(string a){//将hh:mm:ss统一转化成分钟的形式
float min;
min=stof(a.substr(3,2))+stof(a.substr(0,2))*60+stof(a.substr(6,2))/60;
return min;
}
float time1[10001];//记录每个顾客需要花费的时间
float time3[10001];//time[]的copy
float time2[10001];//记录每个顾客到达的时间;
float time4[10001];//time2[]的copy
float wait[10001];//记录每个人的等待时间;
bool cmp_diy(pair2& a,pair2& b){
if((a.first).substr(0,2)!=(b.first).substr(0,2)){//小时部分不相等
return (a.first).substr(0,2)<(b.first).substr(0,2);
}
else{
if((a.first).substr(3,2)!=(b.first).substr(3,2)){
return (a.first).substr(3,2)<(b.first).substr(3,2);
}
else{
return (a.first).substr(6,2)<(b.first).substr(6,2);
}
}
}
int main()
{
int n,m;
queue<int> q;
queue<int> q2; //q的copy,q2用于记录,q用于修改
vector<pair2> vt;//这个容器用来对顾客按时间排序后过渡到数组里
vector<pair2> vt2;
vector<queue<int> >vt3;
vector<queue<int> >vt4;
pair2 pa;
string atime;
float ptime;
int f;//记录有没有空的队列
float min;//各个队列的队首元素的最小值
int mini;//记录最小值的顾客的序号
float cnt;
float wtime=0;//所有顾客的等待总时间 单位:分
float tmp;//记录上一个顾客的结束时间
int pcnt=0;//记录符合要求的人数
cin>>n>>m;
for(int i=0;i<m;i++){
vt3.push_back(q);
vt4.push_back(q2);
}
for(int i=0;i<n;i++){
cin>>atime>>ptime;
pa.first=atime;
pa.second=ptime;
vt.push_back(pa);
vt2.push_back(pa);
}
sort(vt.begin(),vt.begin()+vt.size(),cmp_diy);
for(int i=0;i<vt.size();i++){
f=0;
time1[i]=vt[i].second;
time3[i]=vt[i].second;
time2[i]=to_min(vt[i].first);
time4[i]=to_min(vt[i].first);
if(time2[i]>480){
for(int j=0;j<vt3.size();j++){
if(vt3[j].size()!=0){
time1[vt3[j].front()]=time1[vt3[j].front()]-(time2[i]-480);//如果这个客户来的时候,上个客户已经结束了,那么上个客户出列
if((time1[vt3[j].front()]+max(time2[vt3[j].front()],float(480))-480)<=0){
time1[vt3[j].front()]=time1[vt3[j].front()]+(time2[i]-480);
vt3[j].pop();
}
else{
time1[vt3[j].front()]=time1[vt3[j].front()]+(time2[i]-480);
}
}
}
}
for(int j=0;j<vt3.size();j++){
if(vt3[j].size()==0){//有空的队列
f=1;
vt3[j].push(i);
vt4[j].push(i);
break;
}
}
if(f==0){//没有空的队列,要遍历每个队列找最小值
min=9999999;
for(int j=0;j<vt3.size();j++){
if(time2[(vt3[j].front())]<480){
time2[vt3[j].front()]=480;
}
if(min>(time1[vt3[j].front()]+time2[vt3[j].front()])){
min=time1[vt3[j].front()]+time2[vt3[j].front()];
mini=j;
}
}
//最小值出列
vt3[mini].pop();
vt3[mini].push(i);
vt4[mini].push(i);
for(int j=0;j<vt3.size();j++){
if(j!=mini){
time1[vt3[j].front()]=time1[vt3[j].front()]-min+480;
if((time1[vt3[j].front()]+time2[vt3[j].front()])==0){//等于0就一起出队
vt3[j].pop();
}
}
}
}
}
//在这一步,已可以知道这一天在每个窗口排队的顾客的序号顺序
//等待时间=前一个人的结束时间(或者说自己的开始时间)-自己的到达时间
//time3[]为每个人的服务所花时间
//time4[]为到达银行的时间
//用cnt计算累计时间
//开始服务时间超过下午五点的不算
for(int i=0;i<vt4.size();i++){
cnt=max(float(480),time4[vt4[i].front()]);//上一个人的结束时间
if(vt4[i].size()==0){
continue;
}
while(vt4[i].empty()==false){
if(time4[vt4[i].front()]>1020){//自己到的时间超过五点,就不算了
break;
}
if(time4[vt4[i].front()]>cnt){
tmp=time4[vt4[i].front()]+time3[(vt4[i].front())];
vt4[i].pop();
pcnt++;
}
else{
wtime+=(cnt-(time4[vt4[i].front()]));
cnt+=time3[(vt4[i].front())];
vt4[i].pop();
pcnt++;
}
}
}
if(pcnt==0){
cout<<"0.0";
}
else{
cout<<fixed<<setprecision(1)<<(wtime/pcnt);
}
return 0;
}

浙公网安备 33010602011771号