1. 程式人生 > >1014 Waiting in Line (30 分)C++實現(已AC)

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."; } ```