1014 Waiting in Line (30 分)C++實現(已AC)
阿新 • • 發佈:2018-11-03
題目
題目連結:https://pintia.cn/problem-sets/994805342720868352/problems/994805498207911936
思路:
建立一個視窗列表,每個列表維護一個M長度的佇列, 以及佇列末尾的人服務結束的時間, 逐個插入客戶,當有佇列不滿的時候, 直接插入到當前人數最少的佇列;當所有佇列都滿的時候, 找到隊首客戶服務時間結束最早的佇列,把隊首客戶彈出,並將當前客戶入隊.
坑點:
- 不能使用自帶的時間類,會超時
- 判斷客戶是否能被服務是判斷其開始服務時間是否早於17點, 這個問題對應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.";
}
```