PAT A1014 Waiting in Line

Keywords: Windows iOS

Knowledge Points: Simulation

meaning of the title

The bank has n windows, each window can queue m people. A k user gives the service time of each user. The bank starts service at 8 o'clock. If the windows are not full, they will join the queue. If they are already full, they will stand outside the yellow line and wait. If multiple windows are not full at the same time, choose the queue with the smaller window number. If a user has not started service before 17 o'clock, he will not be served. Give q queries and calculate the end time of customer service.

thinking

The first n*m individual can queue directly in front of the window, while the n*m+1 and future customers can only wait for a window to complete a service and then queue behind the window. Priority queues can be used to get the first completed service
Window. When a person queues up in front of a window, his starting service time is already confirmed.

Code

#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
#include <iomanip>

using namespace std;

#define time2Minute(h, mi) ((h) * 60 + (mi))

struct wq {
    int index;
    int time;

    bool operator>(const wq &b) const {
        if (time != b.time) return time > b.time;
        else return index > b.index;
    }
};

int n, m, k, q;
// The queue before the yellow line
queue<int> waitQ[25];
// Customer processing time When no one queues before the time window when the customer starts to be served
int processTime[1005], serveTime[1005], availableTime[25];

int main() {
    cin.tie(nullptr);
    cout.tie(nullptr);
    ios::sync_with_stdio(false);

    cin >> n >> m >> k >> q;
    for (int i = 1; i <= k; ++i) cin >> processTime[i];

    int startTime = time2Minute(8, 0);
    int endTime = time2Minute(17, 0);

    fill_n(serveTime, k + 1, endTime);
    fill_n(availableTime, 25, startTime);

    // The first n*m users go directly to the Yellow Line and wait to be served
    int nextCustomer = 1;  // Next customer in front of the yellow line
    for (int i = 0; i < m and nextCustomer <= k; ++i) {
        for (int j = 0; j < n and nextCustomer <= k; ++j, ++nextCustomer) {
            waitQ[j].push(nextCustomer);
            serveTime[nextCustomer] = availableTime[j];
            availableTime[j] += processTime[nextCustomer];
        }
    }

    // Priority queue is used to get the window of the first completed service
    priority_queue<wq, vector<wq>, greater<wq>> pq;
    for (int i = 0; i < n; ++i) {
        int top = waitQ[i].front();
        pq.push({i, serveTime[top] + processTime[top]});
    }

    // Starting with the n*m+1 customer, you need to wait for a window to be processed before you can enter the yellow line queue.
    while (nextCustomer <= k) {
        int queue = pq.top().index;

        pq.pop();
        waitQ[queue].pop();

        waitQ[queue].push(nextCustomer);
        serveTime[nextCustomer] = availableTime[queue];
        availableTime[queue] += processTime[nextCustomer];
        ++nextCustomer;

        int top = waitQ[queue].front();
        pq.push({queue, serveTime[top] + processTime[top]});
    }

    for (int i = 0; i < q; ++i) {
        int x;
        cin >> x;

        if (serveTime[x] < endTime) {
            int doneTime = serveTime[x] + processTime[x];
            cout << setw(2) << setfill('0') << doneTime / 60 << ":"
                 << setw(2) << setfill('0') << doneTime % 60 << "\n";
        } else
            cout << "Sorry\n";
    }
}

Posted by abhikerl on Mon, 30 Sep 2019 12:30:19 -0700