1014 Waiting in Line (30 分)C++实现(已AC)

题目

题目链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805498207911936

思路:

创建一个窗口列表,每个列表维护一个M长度的队列, 以及队列末尾的人服务结束的时间, 逐个插入客户,当有队列不满的时候, 直接插入到当前人数最少的队列;当所有队列都满的时候, 找到队首客户服务时间结束最早的队列,把队首客户弹出,并将当前客户入队.

坑点:

  1. 不能使用自带的时间类,会超时
  2. 判断客户是否能被服务是判断其开始服务时间是否早于17点, 这个问题对应3个测试点, 感觉测试点有点神奇.
  3. 类的成员变量在class{}内的都是声明, 只有当类实例化为对象时才被定义, 但是静态成员变量不依赖于实例, 所以需要在类外单独定义.

代码

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;

class Time {
    public:
    int hour;
    int minute;
    Time(int hour = 0, int minute = 0);
    Time operator+(const Time &t) const;
    Time operator+(const int &t) const;
    Time &operator=(const Time &t);
    int gethour() { return hour; } 
    int getminute() {return minute; }
    bool less(const Time &t);

};

struct Person {
    int service_time;
    Time end_time; // the time when the customer leaves queue.
} persons[2000];

class window {
    private:  
    Time back_time; // remark the leave time of the last customer in the queue.
    queue<Person> w_queue; // a queue contains persons in queue.
    public:
    static int capacity; // remark the capacity of queue. this code is a declaration.
    window () : back_time(8, 0) { } // initial the back time to be 8:00
    static void set_capacity(unsigned int init_capacity); // method to modify the capacity of window class
    bool is_full() // whether the queue is full.
    { return w_queue.size() == capacity; }
    void enqueue(Person &p); // enqueue persons with updating the back_time and the end_time of person.
    void dequeue() { w_queue.pop(); } // dequeue person from front.
    Person top() { return w_queue.front(); } // get the front person of queue.
    int cur_in_queue() { return w_queue.size(); } // return the number of persons in queue.
};

int window::capacity = 5; // 静态成员变量需要初始化分配内存空间
/** 
 * switch which window the next customer enqueue. 
 * If there's queue not full, return the queue index of which the the number of current customers in queue is least.
 * If all queues are full, return the queue index in which the front customer leaves first. 
*/
int find_smallest_queue(window w[], int size); 

int main ()
{
    int N, M, K, Q; // N--the number of windows, M--capacity of queue K--people to queue Q-- people to query.
    cin >> N >> M >> K >> Q;
    window::set_capacity(M);
    window* win_list = new window[N];
    for (int k = 1; k <= K; k++) {
        cin >> persons[k].service_time;
        int w_index = find_smallest_queue(win_list, N); // get the queue to enqueue.
        if (win_list[w_index].is_full()) { // if the queue is full, dequeue the first customer so that the front time of queue is updated.
            win_list[w_index].dequeue();
            win_list[w_index].enqueue(persons[k]);
        }
        else {
            win_list[w_index].enqueue(persons[k]); // if the queue isn't full, just enqueue the customer and return the end-service time to this customer.
        }
    }
    Time close_time(17, 0); // set the close time
    while (Q--)
    {
        int query;
        cin >> query;
        if (persons[query].end_time.less(close_time + persons[query].service_time)) {
            printf("%02d:%02d\n", persons[query].end_time.gethour(), persons[query].end_time.getminute());
        }
        else printf("Sorry\n");
    }
    getchar();
    getchar();
    return 0;
}


Time::Time(int hour, int minute) {
    this->hour = hour;
    this->minute = minute;
}
Time Time::operator+(const Time &t) const
{
    Time temp;
    temp.hour = this->hour + t.hour;
    temp.minute = this->minute + t.minute;
    if (temp.minute > 59) {
        temp.minute = temp.minute % 60;
        temp.hour++;
    }
    return temp;
}
Time Time::operator+(const int &t) const
{
    Time temp(this->hour, this->minute + t);
    if (temp.minute > 59) {
        temp.hour += temp.minute / 60;
        temp.minute = temp.minute % 60;
        
    }
    return temp;
}

Time& Time::operator=(const Time &t)
{
    this->hour = t.hour;
    this->minute = t.minute;
    return *this;
}

bool Time::less(const Time &t)
{
    if (this->hour < t.hour) return true;
    else if (this->hour == t.hour && this->minute < t.minute) return true;
    else return false;
}

int find_smallest_queue(window w[], int size)
{
    int best_w = 0;
    int best_size = window::capacity;
    for (int i = 0; i < size; i++) 
    {
        if(!w[i].is_full() && w[i].cur_in_queue() < best_size)
            best_w = i;
            best_size = w[i].cur_in_queue();
    }
    if (best_size < window::capacity) return best_w;
    best_w = 0;
    Time earliest_time(24, 0);
    for (int i = 0; i < size; i++)
    {
        if (w[i].top().end_time.less(earliest_time)) {
            best_w = i;
            earliest_time = w[i].top().end_time;
        }
    }
    return best_w;
}

void window::set_capacity(unsigned int init_capacity)
{
    capacity = init_capacity;
}

void window::enqueue(Person &p) 
    { 
        if (w_queue.size() < capacity) {
            back_time = back_time + p.service_time;
            p.end_time = back_time;
            w_queue.push(p);
        }
        else
            throw "enqueue to a full w_queue.";
    }
    ```
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值