PAT1014 Waiting in Line

题目描述
考点:模拟排队
分析:此题是前面这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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值