我靠!我tm终于ac了,从凌晨1点半写到5点钟,没错,我他妈和它杠上了。
思路:建立N个队列,先将队列内的N*M个人排满(不够就break,多了之后处理)。队列内存consumer的id和当前服务所需的时间,用pair<id,time>即可。
每次寻找队列头的最小值,然后每个队列头的当前所需时间减去最小值(防止多个用户所需时间相等),
当各个队列头为0时,1、更新结果集 2、弹出当前队列头。3、如果有新人,插入
代码:
//顾客只要是在17:00前开始服务的都可以被服务完,所以判断条件里还要加上这一条;及代码中注释部分 真尼玛坑啊 17:00是开始时间,17:59是结束时间
#include<iostream>
#include<vector>
#include<map>
using namespace std;
bool all_empty(vector< pair<int,int> > queues[],int n){
for(int i=0;i<n;i++){
if(queues[i].size()!=0) return false;
}
return true;
}
string to_time(int t){
string ans;
int h=t/60+8+100,m=t%60+100;
string hh=to_string(h),mm=to_string(m);
hh.erase(hh.begin());mm.erase(mm.begin());
ans = hh+":"+mm;
return ans;
}
int main()
{
int n,m,k,q;
cin>>n>>m>>k>>q;
//记总时间
int t=0;
//记结果
map<int,int> ans; //[id]---[08:07]
//生成n个队列
vector< pair<int,int> > queues[n]; //pair<id,time>
//把人放进去
int id=1,time,flag=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(id>k){
flag=1;break;
}
cin>>time;
queues[j].push_back(make_pair(id,time));
id++;
}
if(flag==1) break;
}
//开始把人放出来,如果k》m*n,有人进来再处理就好了。
while( !all_empty(queues,n) ){
//先计算最小值,再都减去最小值,为0的弹出的同时新进人。
int min=999;
for(int i=0;i<n;i++){
if(queues[i].size()==0) continue;
if(queues[i].begin()->second < min) min=queues[i].begin()->second;
}
if(t+min>=540){ //下次循环点就17:00不服务了,把这次的都服务完!!!!!!!!!!!!!!!!!!!测试点5
for(int i=0;i<n;i++){
if(queues[i].size()==0) continue;
auto it=queues[i].begin();
ans[it->first]=(t+it->second);
}
break;
}
t=t+min;
for(int i=0;i<n;i++){
if(queues[i].size()==0) continue;
auto it=queues[i].begin();
it->second -=min;
if(it->second==0){
//弹出it 1、更新结果集 2、如果有新人,插入 3、弹出
ans[it->first]=(t);
queues[i].erase(it); //这里很重要,如果放在后面会报段错误,考虑是不是由于增加了元素导致id变了。!!!!!!!!!!!!!!!!!!!!!!!!!!!!!测试点1
if(id<=k){ //这里虽然队列入队出队结束了,但是还有数没有读完!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!测试点4
cin>>time;
queues[i].push_back(make_pair(id,time));
id++;
}
}
}
}
for(;id<=k;id++){
int temp;
cin>>temp;
}
for(int i=0;i<q;i++){
int q_id;
cin>>q_id;
if(ans.count(q_id) ) cout<<to_time(ans[q_id])<<endl;
else cout<<"Sorry"<<endl;
}
}
巨坑的点!!!!!!!!!!!!!!!!!!
测试点1:段错误
这里我没搞懂,弹出和插入新人的步骤交换后会出现这个结果,考虑是不是push_back把迭代器it给变了。
测试点5:答案错误
这里是大家都反馈的点,是开始时间在17:00之前的,就可以服务到不能呼吸哦!
这里发现之后也是想了好久,在t+min>540后,把当前的服务全部结束掉。
(最开始直接t>540发现有的进行一半的服务被我停止了,因为没记录开始时间,让我一度怀疑自己要重新设计,构建个结构包含开始时间,结束时间啥啥的,当时已经4点了,能懂我崩溃的心情吗)
案例:
2 1 3 3
3 540 540
1 2 3
结果:
08:03
17:00
17:03
测试点4:答案错误
因为我的代码时一边读取一边处理,导致服务时间大于540的时候队列结束了,第2行数据没读取完,就串行了,找了好久。!!!!
案例:
2 1 5 3
3 540 540 1 2
1 2 3
结果:
08:03
17:00
17:03
我之前的错误结果(这样猜一眼发现错哪了):
08:03
17:00
08:03