Zhejiang University Edition "Data Structure (2nd Edition)" Question Collection-Exercise 8.3

Exercise 8.3 Single window "clamped" version of bank queuing problem (30point(s))

Queuing "clogging" is a behavior that arouses strong dissatisfaction, but this phenomenon often exists. In the bank’s single-window queuing problem, suppose that the bank has only one window to provide services, and all customers are arranged in a long queue according to the arrival time. When the window is free, the next customer goes to the window to process the transaction. At this time, if it is known that the i-th customer and the j-th customer in the back are good friends and are willing to handle affairs for the friend, then the transaction processing time of the i-th customer is the time consumed by the office of his own affairs plus the friend’s office Sum. In this case, the customer's waiting time may be affected. Assuming that when everyone arrives at the bank, if there is no empty window, they will request the help of the first friend (including the friend who is receiving the service at the window); when more than one friend asks a customer for help, the customer will base on his friend The order of the request to process the transaction in turn. Try to write a program to simulate this phenomenon and calculate the average waiting time for customers.

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;
vector<Customer> customer;
vector<int> wait;
list<Customer*> queue;

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(make_pair(name, i+1));
        }
    }
    customer.resize(N);
    wait.resize(N);
    for(int i = 0; i < N; i++) {
        cin >> customer[i].name >> customer[i].T >> customer[i].P;
        customer[i].id = circle[customer[i].name];
        queue.push_back(&customer[i]);
    }
    int last_finish = 0;
    for(int i = 0; i < N;) {
        Customer *c = queue.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;
            queue.pop_front();
        } else {
            for(auto x = queue.begin(); x != queue.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 = queue.erase(x);
                --x;
            }
        }
    }
    double sum = 0;
    for(auto &x : wait) sum += x;
    printf("%.1f\n", sum/N);
    return 0;
}

Ideas:

Use the most recent end time to check whether the following friends in the same circle have arrived within the most recent end time, and if so, continue processing;

If there is no circle, it will be handled as the normal team leader.

Guess you like

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