Zhejiang University Edition "Data Structure (Second Edition)" Question Collection-Exercise 8.2

Exercise 8.2 Single-queue multi-window plus VIP service of bank queuing problem (30point(s))

Suppose that the bank has K windows to provide services, and a yellow line is set in front of the window, and all customers line up in a long line after the yellow line according to the arrival time. When a window is free, the next customer will go to the window to process the transaction. When there are multiple windows to choose from, it is assumed that the customer always chooses the window with the lowest number.

Some banks will give VIP customers various preferential services, such as opening up VIP windows. In order to maximize the use of resources, the service mechanism of the VIP window is defined as: when there are no VIP customers in the queue, the window serves ordinary customers; when the window is idle and there are VIP customers waiting in the queue, the VIP that is ranked at the top Customers enjoy the services of this window. At the same time, when it is a VIP customer's turn to go out, if the VIP window is not empty, the customer can choose a free ordinary window; otherwise, the VIP window must be selected .

This question requires to output the average waiting time, longest waiting time, and final completion time of N customers who came to wait for service, and count how many customers are served by each window.

Example

#include <iostream>
#include <cstdio>
#include <vector>
#include <unordered_map>
#include <list>
using namespace std;

struct Customer {
    string name;
    int    T;
    int    P;
    int    id;
};

unordered_map<string, int> circle;
list<Customer> customer;
vector<int> wait;

int main()
{
    int N, M;
    cin >> N >> M;
    circle.reserve(N);
    for (int i = 0; i < M; i++) {
        string name;
        int L;
        cin >> L;
        for(int j = 0; j < L; j++) {
            cin >> name;
            circle.insert({name, i+1});
        }
    }
    wait.resize(N);
    for(int i = 0; i < N; i++) {
        Customer user;
        cin >> user.name >> user.T >> user.P;
        user.id = circle[user.name];
        customer.push_back(user);
    }
    int last_finish = 0;
    for(int i = 0; i < N;) {
        Customer c = customer.front();
        int id = c.id;
        if(last_finish < c.T) last_finish = c.T;
        if(id == 0) {
            wait[i++] = last_finish - c.T;
            last_finish += min(c.P, 60);
            cout << c.name << endl;
            customer.pop_front();
        } else {
            for(auto x = customer.begin(); x != customer.end(); ++x) {
                if(x->T > last_finish) break;
                if(x->id != id) continue;
                wait[i++] = last_finish - x->T;
                last_finish += min(x->P, 60);
                cout << x->name << endl;
                x = customer.erase(x);
                --x;
            }
        }
    }
    double sum = 0;
    for(auto &x : wait) sum += x;
    printf("%.1f\n", sum/N);
    return 0;
}

Ideas:

Set the window end time Final to be greater than or equal to the arrival time of the counterparty, and then find the window with the earliest end time, check whether there is any VIP waiting in the customer queue, and if there is any VIP, check whether the VIP is also in the earliest batch of windows that ended. , Use the Vip window to service Vip, if not, use the window service found earlier to serve the target customer.

Guess you like

Origin blog.csdn.net/u012571715/article/details/113408454