思路
用map存储客户,因为map可以自动排序,对客户到达时间从小到大排序。输入数据时排除17:00:00后的客户,处理时间>1小时的,设为1小时。
时间以string形式存储,可直接比大小。大的就是晚一些的。
用vector数组存储窗口的空闲时间点,初始时间点都设为"08:00:00"。处理一个客户,就将此时间加上客户处理时间。
从最早到达的客户开始,首先找到最先空闲或已空闲的窗口,将此窗口的时间与客户到达时间做对比,若窗口时间小,说明客户到达时窗口就是空闲的,无需等待;若窗口时间大,说明需等待;
代码
#include<iostream>
#include<map>
#include<vector>
#include<iomanip>
#include<string>
using namespace std;
string plustime(string s,int p){//在时间s的基础上加上p分钟,返回对应时间的string形式
int mm = stoi(s.substr(3,2));
int hh = stoi(s.substr(0,2)) + (mm + p) / 60;
mm = (mm + p) % 60;
string h = to_string(hh);
string m = to_string(mm);
if(h.length() != 2)h.insert(0,"0");
if(m.length() != 2)m.insert(0,"0");
s[0] = h[0];s[1] = h[1];
s[3] = m[0];s[4] = m[1];
return s;
}
double subtraction(string s1,string s2){//返回时间s1 - s2之间的分钟数。
int hh,mm,ss;
int hh1 = stoi(s1.substr(0,2));
int hh2 = stoi(s2.substr(0,2));
int mm1 = stoi(s1.substr(3,2));
int mm2 = stoi(s2.substr(3,2));
int ss1 = stoi(s1.substr(6,2));
int ss2 = stoi(s2.substr(6,2));
if(ss1 >= ss2)ss = ss1 - ss2;
else {
ss = ss1 + 60 - ss2;
mm1 -= 1;
}
if(mm1 >= mm2)mm = mm1 - mm2;
else{
mm = mm1 + 60 - mm2;
hh1 -= 1;
}
hh = hh1 - hh2;
return hh * 60 + mm + (double)ss / 60.0;
}
int main(){
int n,k,t,i;
double time = 0;
string s;
cin>>n>>k;
vector<string> v(k,"08:00:00");
map<string,int> mapp;
map<string,int>::iterator it;
for(i = 0;i < n;i ++){
cin>>s>>t;
if(s <= "17:00:00"){
if(t > 60)t = 60;
mapp[s] = t;
}
}
for(it = mapp.begin(); it != mapp.end(); ++ it){
//找到最先空闲的窗口i
string min = v[0];
int min_i = 0;
for(i = 1;i < k; ++ i){
if(v[i] < min){
min = v[i];
min_i = i;
}
}
if(v[min_i] <= it->first){
//立即办理业务,等待时间为0
v[min_i] = plustime(it->first,it->second);
continue;
}
if(v[min_i] > it->first){
//客户需要等待
time += subtraction(v[min_i],it->first);
v[min_i] = plustime(v[min_i],it->second);
}
}
cout<<setiosflags(ios::fixed)<<setprecision(1)<<time / (int)mapp.size()<<endl;
return 0;
}