Untitled

 avatar
unknown
plain_text
a month ago
6.0 kB
5
Indexable
\#include <iostream>
#include <sstream>
using namespace std;

struct EnteredFamilyNode {
    int id, size;
    EnteredFamilyNode* next;
    EnteredFamilyNode(int i, int s) : id(i), size(s), next(NULL) {}
};

struct Family {
    int id, size, price, wait_time, registration_time;
    bool is_special, is_gogo;
    Family* next;
    Family(int i, int s, int p) : id(i), size(s), price(p), wait_time(0), registration_time(2),
                                  is_special(false), is_gogo(s >= 100), next(NULL) {}
};

struct FestivalQueue {
    Family* front;
    Family* rear;
    Family* registration;
    int no_quit_zone, special_offer;
    int total_money, people_entered, people_quit, family_id_counter;
    EnteredFamilyNode* entered_head;
    bool has_special;

    FestivalQueue(int x, int y) : no_quit_zone(x), special_offer(y), registration(NULL),
                                  total_money(0), people_entered(0), people_quit(0),
                                  family_id_counter(1), front(NULL), rear(NULL),
                                  entered_head(NULL), has_special(false) {}

    void process_registration() {
        if (registration) {
            registration->registration_time--;
            if (registration->registration_time == 0) {
                total_money += registration->is_special ? 0 : registration->price;
                people_entered += registration->size;
                EnteredFamilyNode* e = new EnteredFamilyNode(registration->id, registration->size);
                e->next = entered_head;
                entered_head = e;
                if (registration->is_special) has_special = false;
                delete registration;
                registration = NULL;
            }
        }
        if (!registration && front) {
            registration = front;
            front = front->next;
            if (!front) rear = NULL;
        }
    }

    void check_quitting() {
        if (!front) return;
        int position = 0;
        Family* prev = NULL;
        Family* curr = front;
        while (curr) {
            bool can_quit = false;
            if (position >= no_quit_zone && curr->wait_time >= 60 && !curr->is_special) {
                Family* next = curr->next;
                if (!next || (!next->is_special && !next->is_gogo)) {
                    can_quit = true;
                }
            }
            if (can_quit) {
                if (!prev) front = curr->next;
                else prev->next = curr->next;
                if (curr == rear) rear = prev;
                people_quit += curr->size;
                Family* tmp = curr;
                curr = curr->next;
                delete tmp;
            } else {
                prev = curr;
                curr = curr->next;
                position++;
            }
        }
    }

    void check_special_offer() {
        if (special_offer == -1 || has_special) return;
        Family* start = front;
        while (start) {
            int sum = 0;
            Family* mid = start;
            while (mid) {
                sum += mid->price;
                if (sum == special_offer && mid->next) {
                    mid->next->is_special = true;
                    has_special = true;
                    return;
                }
                if (sum > special_offer) break;
                mid = mid->next;
            }
            start = start->next;
        }
    }

    void add_family(int size, int price) {
        Family* new_family = new Family(family_id_counter++, size, price);
        if (!rear) front = rear = new_family;
        else rear->next = new_family, rear = new_family;
    }

    void update_wait_times() {
        for (Family* curr = front; curr; curr = curr->next) curr->wait_time++;
    }

    void process_minute() {
        process_registration();
        check_quitting();
        update_wait_times();
        check_special_offer();
    }

    void print_summary(int place) {
        cout << "Place " << place << " Summary\n";
        cout << "Total Money: " << total_money << "\n";
        cout << "Total People Entered: " << people_entered << "\n";
        cout << "Total People Quit: " << people_quit << "\n";
        int qcount = 0;
        for (Family* curr = front; curr; curr = curr->next) qcount += curr->size;
        if (registration) qcount += registration->size;
        cout << "Current People Queuing: " << qcount << "\n\n";
        cout << "Entered Families :\n";
        for (EnteredFamilyNode* it = entered_head; it; it = it->next) {
            cout << "Family " << it->id << " with " << it->size << " people\n";
        }
        cout << "\n";
    }
};

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

    int F, X, Y, M;
    cin >> F >> X >> Y >> M;
    cin.ignore();

    FestivalQueue** queues = new FestivalQueue*[F];
    for (int i = 0; i < F; ++i)
        queues[i] = new FestivalQueue(X, Y);

    for (int i = 0; i < F; ++i) {
        string line;
        getline(cin, line);
        if (line == "0") continue;
        stringstream ss(line);
        int A, P;
        char comma;
        while (ss >> A >> comma >> P) queues[i]->add_family(A, P);
    }

    for (int t = 0; t < M; ++t) {
        string* lines = new string[F];
        for (int i = 0; i < F; ++i) {
            getline(cin, lines[i]);
        }
        for (int i = 0; i < F; ++i) {
            if (lines[i] == "0") continue;
            stringstream ss(lines[i]);
            int A, P;
            char comma;
            while (ss >> A >> comma >> P) queues[i]->add_family(A, P);
        }
        for (int i = 0; i < F; ++i)
            queues[i]->process_minute();
        delete[] lines;
    }

    for (int i = 0; i < F; ++i) {
        queues[i]->print_summary(i);
        delete queues[i];
    }
    delete[] queues;
    return 0;
}
Editor is loading...
Leave a Comment