Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <limits.h>
- //Structura pentru jucator:
- struct Player
- {
- char *last_name;
- char *first_name;
- int score;
- };
- typedef struct Player Player;
- //Structura pentru tara:
- //in aceasta structura implementez si lista necesara
- struct Country
- {
- char *name;
- int nr_players;
- int global_score;
- Player *players;
- struct Country *next;
- struct Country *prev;
- };
- typedef struct Country Node;
- //Structura pentru coada
- struct Q
- {
- Node *front, *rear;
- };
- typedef struct Q Queue;
- //mai jos avem prototipuri pentru functiile create mai jos
- void insertAtEnd(Node *head, FILE **f);
- void openFiles(char *sir1, char *sir2, char *sir3, FILE **f1, FILE **f2, FILE **f3);
- void readList(Node **head, FILE **f, int *nr_teams);
- void afisareLista(Node *head, FILE **f3);
- int putere2(int n);
- float medie(Node *p);
- void deleteNode(Node *head, char *name);
- void stergere_tari(Node *head, int *nr_teams);
- void push_stack(Node **top, Node *curr);
- void createStack(Node **top, Node *head);
- Queue *creare_coada();
- void enQueue(Queue *q, Node *p);
- Node *deQueue(Queue *q);
- Node *pop(Node **top);
- void stergere_stiva(Node **top);
- void calculare_scor(Queue *q, Node **top_winners, FILE **f);
- void switch_stacks(Node **top, Node **top_winners);
- void show_winners(Node *top_winners, FILE **f3);
- void concurs(Node *top, Node **top_winners, int nr_teams, FILE **f3);
- int main(int argc, char *argv[])
- {
- int nr_teams, c1, c2, c3, c4, c5; //variabilele c1,c2,c3,c4 si c5 imi folosesc la realizarea celor 5 task-uri
- char sir1[100], sir2[100], sir3[100]; //folosesc aceste siruri pentru a salva in ele argumentele necesare din fisierul cerinte.in
- strcpy(sir1, argv[1]); //copiez argumentele cum am spus mai sus
- strcpy(sir2, argv[2]);
- strcpy(sir3, argv[3]);
- Node *head = NULL; // initializez inceputul listei cu null
- FILE *f1, *f2, *f3;
- Node *top = NULL;
- Node *top_winners = NULL;
- openFiles(sir1, sir2, sir3, &f1, &f2, &f3); //deschid fisierele pentru citire si pentru scriere in acelasi timp
- fscanf(f1, "%d %d %d %d %d", &c1, &c2, &c3, &c4, &c5); // citesc argumentele din cerinte.in
- readList(&head, &f2, &nr_teams); //citesc lista din fiserul date.in si inserez numele tarilor in functie de numarul de echipe din competitie
- if (c2 == c1)
- {
- stergere_tari(head, &nr_teams); // apelez funtia de stergere a tarilor care au cea mai mica medie pana ajung la un numar de 32 de echipe
- }
- if (c3 == 1)
- {
- createStack(&top, head);
- concurs(top, &top_winners, nr_teams, &f3);
- }
- afisareLista(head, &f3);
- return 0;
- }
- void afisareLista(Node *head, FILE **f3)
- {
- Node *curr = head->next; //ma pozitionez la inceputul listei
- while (curr != head) // parcurg lista
- {
- fprintf(*f3, "%s\n", curr->name); //scriu in fisierul de output numele tarilor
- curr = curr->next;
- }
- }
- void readList(Node **head, FILE **f, int *nr_teams) // in aceasta functie creez santinela pentru aceasta lista si introducem numele tarilor
- {
- int i;
- (*head) = (Node *)malloc(sizeof(Node)); //aloc spatiu pentru nodul de la inceput si incep sa parcurg lista
- (*head)->next = (*head); //aici creez santinela necesara
- (*head)->prev = (*head);
- fscanf(*f, "%d", nr_teams); // citesc numarul de echipe din fiser, mai exact 34
- for (i = 0; i < (*nr_teams); i++) //parcurg lista in functie de numarul de echipe
- {
- insertAtEnd((*head), &(*f)); // apelez functia pentru inserare la finalul listei, care la inceput a fost goala
- }
- }
- void insertAtEnd(Node *head, FILE **f) //functia necesara pentru inserare de elemente la finalul listei circulare
- {
- Node *curr = head; //creez un nod pe care il pointam la inceput
- int i;
- char sir[100]; // in acest sir adaug numele jucatorilor din tarile date
- Node *newNode = (Node *)malloc(sizeof(Node)); // aloc spatiu pentru un nou nod
- fscanf(*f, "%d", &newNode->nr_players); //citesc din fiser numarul de playeri
- fscanf(*f, "%s", sir);
- newNode->name = malloc(strlen(sir) + 1); // aloc spatiu pentru numele jucatorilor
- strcpy(newNode->name, sir); //copiez in sir numele jucatorilor
- newNode->players = malloc(sizeof(Player) * newNode->nr_players); // aloc spatiu in lista pentru jucatori
- for (i = 0; i < newNode->nr_players; i++) //parcurg lista in funtie de nr de jucatori
- {
- fscanf(*f, "%s", sir); //adaug numele jucatorilor in sir
- newNode->players[i].last_name = malloc(strlen(sir) + 1); //aloc spatiu in memorie
- strcpy(newNode->players[i].last_name, sir);
- fscanf(*f, "%s", sir); // fac acelasi lucru ca mai sus si pentru prenume
- newNode->players[i].first_name = malloc(strlen(sir) + 1);
- strcpy(newNode->players[i].first_name, sir);
- fscanf(*f, "%d", &newNode->players[i].score); // citesc din fiser scorul pentru fiecare jucator
- }
- while (curr->next != head)
- {
- curr = curr->next; //parcurg lista
- }
- curr->next = newNode; // fac lista circulara
- newNode->next = head;
- newNode->prev = curr;
- head->prev = newNode;
- }
- // functia necesara pentru citirea si scrierea in fisiere
- void openFiles(char *sir1, char *sir2, char *sir3, FILE **f1, FILE **f2, FILE **f3)
- {
- if ((*f1 = fopen(sir1, "r")) == NULL) //aici citesc din cerinte.in si adaug in main in sirul 1
- {
- fprintf(stderr, "Fisierul nu a putut fi deschis\n");
- exit(1);
- }
- if ((*f2 = fopen(sir2, "r")) == NULL) // citesc din fisierul date.in pentru informatiile necesare la rezolvare
- {
- fprintf(stderr, "Fisierul nu a putut fi deschis\n");
- exit(1);
- }
- if ((*f3 = fopen(sir3, "w")) == NULL) // deschid fisierul de date.out pentru a scrie in el
- {
- fprintf(stderr, "Fisierul nu a putut fi deschis\n");
- exit(1);
- }
- }
- int putere2(int n) // n e numarul de echipe
- {
- int putere = 2; // in aceasta functie verific daca numarul de echipe este putere a lui 2, mai exact 2^5
- for (int i = 1;; i++)
- {
- if (putere * 2 > n)
- return putere;
- else
- putere = putere * 2;
- }
- }
- float medie(Node *p) //functia primeste o tara si returneaza media pentru tara respectiva
- {
- float medie = 0; //initializez media cu 0 pentru a aduna scorurile fiecarui jucator
- int i;
- for (i = 0; i < p->nr_players; i++) // parcurg in functie de numarul de jucator
- {
- medie += p->players[i].score; //adun scorurile
- }
- medie = medie / p->nr_players; //fac media pentru fiecare jucator si o returnez
- return medie;
- }
- void deleteNode(Node *head, char *name) //functia necesara pentru stergerea nodului in funtie de medie si puterea lui 2
- {
- if (head->next == NULL)
- return;
- Node *headcopy = head->next; // creez un nod nou pe care il pointez fix dupa inceputul listei
- while (headcopy != head)
- {
- if (!strcmp(headcopy->name, name)) // compar numele din nod cu numele echipei care trebuie sa il sterg
- {
- headcopy->prev->next = headcopy->next; // avem lista circulara si ne trebuie acest algoritm pentru a-l parcurge
- headcopy->next->prev = headcopy->prev; // am vazut in curs!!
- free(headcopy); //stergem nodul cu echipa aleasa
- break;
- }
- headcopy = headcopy->next; // parcurgem lista
- }
- }
- void stergere_tari(Node *head, int *nr_teams)
- {
- Node *curr;
- float minim;
- while ((*nr_teams) != putere2(*nr_teams)) //cat timp numarul de tari nu este putere a lui 2 facem urmatoarele
- {
- curr = head->next; //ne pozitionam la inceputul listei
- minim = medie(head->next); //facem media primului element si il consideram ca fiind cea mai
- while (curr != head) //parcurgem lista ca sa facem minimul
- {
- if (minim > medie(curr))
- { //daca minimul e mai mare decat media din curr actualizam minimul
- minim = medie(curr);
- }
- curr = curr->next;
- } //la sfarsit aici o sa avem cel mai mic scor (in minim) dintre toate tarile
- curr = head->next; //ne pozitionam iar la inceputul listei
- while (curr != head)
- { //parcugem iar lista ca sa vedem care e prima tara cu scorul minim
- if (medie(curr) == minim)
- {
- deleteNode(head, curr->name); //apelam funtia pentru stergere
- (*nr_teams)--; //dupa stergere scadem numarul echipelor
- break;
- }
- curr = curr->next;
- } //si continua ciclul
- }
- }
- int isEmpty(Node *top)
- {
- return top == NULL;
- }
- void push_stack(Node **top, Node *curr)
- {
- char sir_stiva[500]; // creez un sir in care voi adauga numele si prenumele jucatorilor
- Node *newNode = (Node *)malloc(sizeof(Node)); //aloc spatiu pentru fiecare camp din structura urmand adaugarea in stiva
- newNode->name = malloc(strlen(curr->name) + 1); //aloc spatiu pentru numele jucatorilor
- strcpy(newNode->name, curr->name); //copiez numele in noul nod, fiind un sir de caractere
- newNode->nr_players = curr->nr_players; //numarul de playeri in adaug in noul nod pentru a ma ajuta la indexare
- newNode->players = malloc(newNode->nr_players * sizeof(Player)); //alocam spatiu si pentru jucatori
- newNode->global_score = curr->global_score; //trec si scorul global in noul nod
- for (int i = 0; i < curr->nr_players; i++) //parcurg in functie de numarul de playeri
- {
- newNode->players[i].first_name = malloc(strlen(curr->players[i].first_name) + 1); //aloc spatiu pentru prenume
- strcpy(newNode->players[i].first_name, curr->players[i].first_name); //adaug numele si prenumele in sirul creat
- newNode->players[i].last_name = malloc(strlen(curr->players[i].last_name) + 1); //aloc spatiu pentru prenume
- strcpy(newNode->players[i].last_name, curr->players[i].last_name);
- newNode->players[i].score = curr->players[i].score; //trec scorurile in noul nod
- }
- //facem ca noul nod sa devina capul listei, ca in functia addAtBeginning
- newNode->next = (*top);
- (*top) = newNode;
- }
- void createStack(Node **top, Node *head)
- {
- Node *curr = head->next;
- while (curr != head)
- {
- push_stack(&(*top), curr);
- curr = curr->next;
- }
- }
- Queue *creare_coada()
- {
- Queue *p;
- p = (Queue *)malloc(sizeof(Queue));
- if (p == NULL)
- {
- printf("Alocare dinamica esuata!");
- exit(1);
- }
- p->front = NULL;
- p->rear = NULL;
- return p;
- };
- /*void enQueue(Queue *q, Node *p)
- {
- if (q->rear == NULL)
- q->rear = p;
- else
- {
- q->rear->prev = p;
- q->rear = p;
- }
- if (q->front == NULL)
- q->front = q->rear;
- }
- Node *deQueue(Queue *q)
- {
- Node *p, *m;
- m = (Node *)malloc(sizeof(Node));
- p = q->front;
- m->name = malloc(sizeof(char) * (strlen(p->name) + 1));
- strcpy(m->name, p->name);
- m->global_score = p->global_score;
- q->front = (q->front)->prev;
- free(p);
- return m;
- }*/
- Node *pop(Node **top)
- {
- Node *m;
- m = *top;
- (*top) = (*top)->next;
- return m;
- }
- void stergere_stiva(Node **top)
- {
- Node *p;
- while ((*top) != NULL)
- {
- p = *top;
- *top = (*top)->next;
- free(p);
- }
- }
- void calculare_scor(Queue *q, Node **top_winners, FILE **f)
- {
- int suma1 = 0, suma2 = 0, i, j;
- fprintf(*f, "\n%s %d ----- %s %d\n", q->front->name, q->front->global_score, q->rear->name, q->rear->global_score);
- for (i = 0; i < q->front->nr_players; i++)
- for (j = 0; j < q->rear->nr_players; j++)
- {
- fprintf(*f, "%s %s %d vs %s %s %d\n", q->front->players[i].last_name, q->front->players[i].first_name, q->front->players[i].score, q->rear->players[j].last_name, q->rear->players[j].first_name, q->rear->players[j].score);
- if (q->front->players[i].score > q->rear->players[j].score)
- {
- q->front->players[i].score += 5;
- suma1 += 3;
- }
- else if (q->front->players[i].score < q->rear->players[j].score)
- {
- q->rear->players[j].score += 5;
- suma2 += 3;
- }
- else
- {
- q->front->players[i].score += 2;
- suma1 += 1;
- q->rear->players[j].score += 2;
- suma2 += 1;
- }
- }
- q->front->global_score += suma1;
- q->rear->global_score += suma2;
- if (suma1 > suma2)
- {
- push_stack(&(*top_winners), q->front);
- }
- else
- {
- push_stack(&(*top_winners), q->rear);
- }
- }
- void switch_stacks(Node **top, Node **top_winners)
- {
- Node *curr = *top_winners;
- Node *aux = NULL;
- while (curr != NULL)
- {
- push_stack(&(*top), curr);
- aux = curr;
- curr = curr->next;
- free(aux);
- }
- }
- void show_winners(Node *top_winners, FILE **f3)
- {
- Node *curr = top_winners;
- fprintf(*f3, "=== WINNER ===\n");
- while (curr != NULL)
- {
- fprintf(*f3, "%s --- %d\n", curr->name, curr->global_score);
- curr = curr->next;
- }
- }
- void concurs(Node *top, Node **top_winners, int nr_teams, FILE **f3)
- {
- int i, j = 0,k = nr_teams;
- Node *aux;
- Queue *q = NULL;
- for (i = 0; k % 2 == 0; i++)
- {
- aux = top;
- while (!isEmpty(aux))
- {
- fprintf(*f3, "====== ETAPA %d ======\n", j++);
- q = creare_coada();
- if(!isEmpty(aux))
- q->front = pop(&aux);
- if(!isEmpty(aux))
- q->rear = pop(&aux);
- calculare_scor(q, &(*top_winners), &(*f3));
- free(q);
- }
- show_winners(*top_winners, &(*f3));
- stergere_stiva(&top);
- top = NULL;
- switch_stacks(&top, &(*top_winners));
- k = k/2;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement