题目描述
考点:模拟排队
分析:此题是前面这14题中最为复杂的。。。主要思路就是模拟整个排队的过程。
数据结构分析: 需要开辟的数据结构有两个结构体数组:1)Customer:保存每个客户的信息,需要保存开始服务的时间和结束服务的时间。2)Window:用来记录当前窗口服务的状态信息。里面的属性有在这个窗口里等待的用户队列以及当前服务的用户指针。
模拟过程分析: 一开始初始化,让每个用户占满窗口以及等候区。之后开始真正模拟。客户id由小到大依次枚举,发现哪一个窗口的结束时间最早(遍历每个窗口的队头客户元素,看哪一个最早完成),就将这个客户归到这个窗口中入队,同时让这个窗口队头的客户出队,同时更新自己窗口的最早完成时间(队头指针往下移动指向下一个客户元素)。
注意: 此题是客户开始被服务的时间要<17:00,不是指完成时间<17:00。
//一个数组 元素:用来保存窗口结构体
//循环模拟排队过程
#include<iostream>
#include<cstring>
using namespace std;
const int N = 1010;
int st[N];
struct Cusfomers{
string star_time;//开始办理业务的时间
string end_time;//完成业务的时间
}customers[N];
struct Window{
int cur_num;//当前窗口服务的人数
Cusfomers serve_customer[N];//排队等候窗口的顾客
int idx = 0;//当前服务到哪一个顾客
int cnt = 0;//总共的顾客数
}windows[30];
int n,m,k,q;
string convert_time(string time,int wt){
int h = wt / 60;
int m = wt % 60;
//cout<<time.substr(0,2)<<time.substr(3,2)<<endl;
int new_h = stoi(time.substr(0,2))+h;
int new_m = stoi(time.substr(3,2))+m;
new_h += (new_m / 60);
new_m %= 60;
string sh,sm;
if(new_h < 10)
sh = "0" + to_string(new_h);
else sh = to_string(new_h);
if(new_m < 10)
sm = "0" + to_string(new_m);
else sm = to_string(new_m);
return sh + ":" + sm;
}
int find_min_time(){
string min_time = "99:99";
int min_index = -1;
for(int i = 0;i < n;i++){
if(min_time > windows[i].serve_customer[windows[i].idx].end_time)
{
min_time = windows[i].serve_customer[windows[i].idx].end_time;
min_index = i;
}
}
windows[min_index].idx++;
return min_index;
}
int main(){
cin>>n>>m>>k>>q;
for(int i = 0;i < k;i++) cin>>st[i];
int index = 0;
while(index < n*m){//初始化,先把黄色线以内的送去窗口排队
for(int i = 0;i < n;i++){
if(windows[i].cnt != 0){
customers[index].star_time = windows[i].serve_customer[windows[i].cnt-1].end_time;
customers[index].end_time = convert_time(windows[i].serve_customer[windows[i].cnt-1].end_time,st[index]);
}
else{
customers[index].star_time = "08:00";
customers[index].end_time = convert_time("08:00",st[index]);
}
windows[i].serve_customer[windows[i].cnt++] = customers[index];
index++;
if(index > k)
break;
}
}
while(index < k){
int min_id = find_min_time();//找到最短可以被服务的时间窗口id
customers[index].star_time = windows[min_id].serve_customer[windows[min_id].cnt-1].end_time;
customers[index].end_time = convert_time(windows[min_id].serve_customer[windows[min_id].cnt-1].end_time,st[index]);
windows[min_id].serve_customer[windows[min_id].cnt++] = customers[index];
index++;
}
while(q--){
int qq;
cin>>qq;
if(customers[qq-1].star_time < "17:00")//要求开始被服务的时间<17:00
cout<<customers[qq-1].end_time<<endl;
else cout<<"Sorry"<<endl;
}
return 0;
}