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;
}
posted @ 2022-07-21 14:16  qwasdasd  阅读(46)  评论(0)    收藏  举报