Advertisement
Guest User

Untitled

a guest
Mar 28th, 2020
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.31 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <limits.h>
  5.  
  6. //Structura pentru jucator:
  7. struct Player
  8. {
  9. char *last_name;
  10. char *first_name;
  11. int score;
  12. };
  13. typedef struct Player Player;
  14.  
  15. //Structura pentru tara:
  16. //in aceasta structura implementez si lista necesara
  17. struct Country
  18. {
  19. char *name;
  20. int nr_players;
  21. int global_score;
  22. Player *players;
  23. struct Country *next;
  24. struct Country *prev;
  25. };
  26. typedef struct Country Node;
  27.  
  28. //Structura pentru coada
  29. struct Q
  30. {
  31. Node *front, *rear;
  32. };
  33. typedef struct Q Queue;
  34.  
  35. //mai jos avem prototipuri pentru functiile create mai jos
  36. void insertAtEnd(Node *head, FILE **f);
  37. void openFiles(char *sir1, char *sir2, char *sir3, FILE **f1, FILE **f2, FILE **f3);
  38. void readList(Node **head, FILE **f, int *nr_teams);
  39. void afisareLista(Node *head, FILE **f3);
  40. int putere2(int n);
  41. float medie(Node *p);
  42. void deleteNode(Node *head, char *name);
  43. void stergere_tari(Node *head, int *nr_teams);
  44. void push_stack(Node **top, Node *curr);
  45. void createStack(Node **top, Node *head);
  46. Queue *creare_coada();
  47. void enQueue(Queue *q, Node *p);
  48. Node *deQueue(Queue *q);
  49. Node *pop(Node **top);
  50. void stergere_stiva(Node **top);
  51. void calculare_scor(Queue *q, Node **top_winners, FILE **f);
  52. void switch_stacks(Node **top, Node **top_winners);
  53. void show_winners(Node *top_winners, FILE **f3);
  54. void concurs(Node *top, Node **top_winners, int nr_teams, FILE **f3);
  55.  
  56. int main(int argc, char *argv[])
  57. {
  58. int nr_teams, c1, c2, c3, c4, c5; //variabilele c1,c2,c3,c4 si c5 imi folosesc la realizarea celor 5 task-uri
  59. char sir1[100], sir2[100], sir3[100]; //folosesc aceste siruri pentru a salva in ele argumentele necesare din fisierul cerinte.in
  60. strcpy(sir1, argv[1]); //copiez argumentele cum am spus mai sus
  61. strcpy(sir2, argv[2]);
  62. strcpy(sir3, argv[3]);
  63. Node *head = NULL; // initializez inceputul listei cu null
  64. FILE *f1, *f2, *f3;
  65. Node *top = NULL;
  66. Node *top_winners = NULL;
  67.  
  68. openFiles(sir1, sir2, sir3, &f1, &f2, &f3); //deschid fisierele pentru citire si pentru scriere in acelasi timp
  69.  
  70. fscanf(f1, "%d %d %d %d %d", &c1, &c2, &c3, &c4, &c5); // citesc argumentele din cerinte.in
  71.  
  72. readList(&head, &f2, &nr_teams); //citesc lista din fiserul date.in si inserez numele tarilor in functie de numarul de echipe din competitie
  73.  
  74. if (c2 == c1)
  75. {
  76. 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
  77. }
  78. if (c3 == 1)
  79. {
  80. createStack(&top, head);
  81. concurs(top, &top_winners, nr_teams, &f3);
  82. }
  83.  
  84. afisareLista(head, &f3);
  85. return 0;
  86. }
  87.  
  88. void afisareLista(Node *head, FILE **f3)
  89. {
  90. Node *curr = head->next; //ma pozitionez la inceputul listei
  91. while (curr != head) // parcurg lista
  92. {
  93. fprintf(*f3, "%s\n", curr->name); //scriu in fisierul de output numele tarilor
  94. curr = curr->next;
  95. }
  96. }
  97.  
  98. void readList(Node **head, FILE **f, int *nr_teams) // in aceasta functie creez santinela pentru aceasta lista si introducem numele tarilor
  99. {
  100. int i;
  101.  
  102. (*head) = (Node *)malloc(sizeof(Node)); //aloc spatiu pentru nodul de la inceput si incep sa parcurg lista
  103. (*head)->next = (*head); //aici creez santinela necesara
  104. (*head)->prev = (*head);
  105. fscanf(*f, "%d", nr_teams); // citesc numarul de echipe din fiser, mai exact 34
  106.  
  107. for (i = 0; i < (*nr_teams); i++) //parcurg lista in functie de numarul de echipe
  108. {
  109. insertAtEnd((*head), &(*f)); // apelez functia pentru inserare la finalul listei, care la inceput a fost goala
  110. }
  111. }
  112.  
  113. void insertAtEnd(Node *head, FILE **f) //functia necesara pentru inserare de elemente la finalul listei circulare
  114. {
  115.  
  116. Node *curr = head; //creez un nod pe care il pointam la inceput
  117. int i;
  118. char sir[100]; // in acest sir adaug numele jucatorilor din tarile date
  119.  
  120. Node *newNode = (Node *)malloc(sizeof(Node)); // aloc spatiu pentru un nou nod
  121. fscanf(*f, "%d", &newNode->nr_players); //citesc din fiser numarul de playeri
  122. fscanf(*f, "%s", sir);
  123. newNode->name = malloc(strlen(sir) + 1); // aloc spatiu pentru numele jucatorilor
  124. strcpy(newNode->name, sir); //copiez in sir numele jucatorilor
  125.  
  126. newNode->players = malloc(sizeof(Player) * newNode->nr_players); // aloc spatiu in lista pentru jucatori
  127.  
  128. for (i = 0; i < newNode->nr_players; i++) //parcurg lista in funtie de nr de jucatori
  129. {
  130. fscanf(*f, "%s", sir); //adaug numele jucatorilor in sir
  131. newNode->players[i].last_name = malloc(strlen(sir) + 1); //aloc spatiu in memorie
  132. strcpy(newNode->players[i].last_name, sir);
  133.  
  134. fscanf(*f, "%s", sir); // fac acelasi lucru ca mai sus si pentru prenume
  135. newNode->players[i].first_name = malloc(strlen(sir) + 1);
  136. strcpy(newNode->players[i].first_name, sir);
  137.  
  138. fscanf(*f, "%d", &newNode->players[i].score); // citesc din fiser scorul pentru fiecare jucator
  139. }
  140.  
  141. while (curr->next != head)
  142. {
  143. curr = curr->next; //parcurg lista
  144. }
  145. curr->next = newNode; // fac lista circulara
  146. newNode->next = head;
  147. newNode->prev = curr;
  148. head->prev = newNode;
  149. }
  150. // functia necesara pentru citirea si scrierea in fisiere
  151. void openFiles(char *sir1, char *sir2, char *sir3, FILE **f1, FILE **f2, FILE **f3)
  152. {
  153. if ((*f1 = fopen(sir1, "r")) == NULL) //aici citesc din cerinte.in si adaug in main in sirul 1
  154. {
  155. fprintf(stderr, "Fisierul nu a putut fi deschis\n");
  156. exit(1);
  157. }
  158. if ((*f2 = fopen(sir2, "r")) == NULL) // citesc din fisierul date.in pentru informatiile necesare la rezolvare
  159. {
  160. fprintf(stderr, "Fisierul nu a putut fi deschis\n");
  161. exit(1);
  162. }
  163. if ((*f3 = fopen(sir3, "w")) == NULL) // deschid fisierul de date.out pentru a scrie in el
  164. {
  165. fprintf(stderr, "Fisierul nu a putut fi deschis\n");
  166. exit(1);
  167. }
  168. }
  169.  
  170. int putere2(int n) // n e numarul de echipe
  171. {
  172. int putere = 2; // in aceasta functie verific daca numarul de echipe este putere a lui 2, mai exact 2^5
  173. for (int i = 1;; i++)
  174. {
  175. if (putere * 2 > n)
  176. return putere;
  177. else
  178. putere = putere * 2;
  179. }
  180. }
  181.  
  182. float medie(Node *p) //functia primeste o tara si returneaza media pentru tara respectiva
  183. {
  184. float medie = 0; //initializez media cu 0 pentru a aduna scorurile fiecarui jucator
  185. int i;
  186. for (i = 0; i < p->nr_players; i++) // parcurg in functie de numarul de jucator
  187. {
  188. medie += p->players[i].score; //adun scorurile
  189. }
  190. medie = medie / p->nr_players; //fac media pentru fiecare jucator si o returnez
  191. return medie;
  192. }
  193.  
  194. void deleteNode(Node *head, char *name) //functia necesara pentru stergerea nodului in funtie de medie si puterea lui 2
  195. {
  196. if (head->next == NULL)
  197. return;
  198. Node *headcopy = head->next; // creez un nod nou pe care il pointez fix dupa inceputul listei
  199.  
  200. while (headcopy != head)
  201. {
  202. if (!strcmp(headcopy->name, name)) // compar numele din nod cu numele echipei care trebuie sa il sterg
  203. {
  204. headcopy->prev->next = headcopy->next; // avem lista circulara si ne trebuie acest algoritm pentru a-l parcurge
  205. headcopy->next->prev = headcopy->prev; // am vazut in curs!!
  206. free(headcopy); //stergem nodul cu echipa aleasa
  207. break;
  208. }
  209. headcopy = headcopy->next; // parcurgem lista
  210. }
  211. }
  212.  
  213. void stergere_tari(Node *head, int *nr_teams)
  214. {
  215. Node *curr;
  216. float minim;
  217. while ((*nr_teams) != putere2(*nr_teams)) //cat timp numarul de tari nu este putere a lui 2 facem urmatoarele
  218. {
  219. curr = head->next; //ne pozitionam la inceputul listei
  220. minim = medie(head->next); //facem media primului element si il consideram ca fiind cea mai
  221. while (curr != head) //parcurgem lista ca sa facem minimul
  222. {
  223. if (minim > medie(curr))
  224. { //daca minimul e mai mare decat media din curr actualizam minimul
  225. minim = medie(curr);
  226. }
  227. curr = curr->next;
  228. } //la sfarsit aici o sa avem cel mai mic scor (in minim) dintre toate tarile
  229. curr = head->next; //ne pozitionam iar la inceputul listei
  230. while (curr != head)
  231. { //parcugem iar lista ca sa vedem care e prima tara cu scorul minim
  232. if (medie(curr) == minim)
  233. {
  234. deleteNode(head, curr->name); //apelam funtia pentru stergere
  235. (*nr_teams)--; //dupa stergere scadem numarul echipelor
  236. break;
  237. }
  238. curr = curr->next;
  239. } //si continua ciclul
  240. }
  241. }
  242.  
  243. int isEmpty(Node *top)
  244. {
  245. return top == NULL;
  246. }
  247.  
  248. void push_stack(Node **top, Node *curr)
  249. {
  250. char sir_stiva[500]; // creez un sir in care voi adauga numele si prenumele jucatorilor
  251. Node *newNode = (Node *)malloc(sizeof(Node)); //aloc spatiu pentru fiecare camp din structura urmand adaugarea in stiva
  252. newNode->name = malloc(strlen(curr->name) + 1); //aloc spatiu pentru numele jucatorilor
  253. strcpy(newNode->name, curr->name); //copiez numele in noul nod, fiind un sir de caractere
  254. newNode->nr_players = curr->nr_players; //numarul de playeri in adaug in noul nod pentru a ma ajuta la indexare
  255. newNode->players = malloc(newNode->nr_players * sizeof(Player)); //alocam spatiu si pentru jucatori
  256. newNode->global_score = curr->global_score; //trec si scorul global in noul nod
  257.  
  258. for (int i = 0; i < curr->nr_players; i++) //parcurg in functie de numarul de playeri
  259. {
  260. newNode->players[i].first_name = malloc(strlen(curr->players[i].first_name) + 1); //aloc spatiu pentru prenume
  261. strcpy(newNode->players[i].first_name, curr->players[i].first_name); //adaug numele si prenumele in sirul creat
  262. newNode->players[i].last_name = malloc(strlen(curr->players[i].last_name) + 1); //aloc spatiu pentru prenume
  263. strcpy(newNode->players[i].last_name, curr->players[i].last_name);
  264. newNode->players[i].score = curr->players[i].score; //trec scorurile in noul nod
  265. }
  266. //facem ca noul nod sa devina capul listei, ca in functia addAtBeginning
  267. newNode->next = (*top);
  268. (*top) = newNode;
  269. }
  270.  
  271. void createStack(Node **top, Node *head)
  272. {
  273. Node *curr = head->next;
  274. while (curr != head)
  275. {
  276. push_stack(&(*top), curr);
  277. curr = curr->next;
  278. }
  279. }
  280.  
  281. Queue *creare_coada()
  282. {
  283. Queue *p;
  284. p = (Queue *)malloc(sizeof(Queue));
  285. if (p == NULL)
  286. {
  287. printf("Alocare dinamica esuata!");
  288. exit(1);
  289. }
  290. p->front = NULL;
  291. p->rear = NULL;
  292. return p;
  293. };
  294.  
  295. /*void enQueue(Queue *q, Node *p)
  296. {
  297. if (q->rear == NULL)
  298. q->rear = p;
  299. else
  300. {
  301. q->rear->prev = p;
  302. q->rear = p;
  303. }
  304. if (q->front == NULL)
  305. q->front = q->rear;
  306. }
  307.  
  308. Node *deQueue(Queue *q)
  309. {
  310. Node *p, *m;
  311. m = (Node *)malloc(sizeof(Node));
  312. p = q->front;
  313. m->name = malloc(sizeof(char) * (strlen(p->name) + 1));
  314. strcpy(m->name, p->name);
  315. m->global_score = p->global_score;
  316. q->front = (q->front)->prev;
  317. free(p);
  318. return m;
  319. }*/
  320.  
  321. Node *pop(Node **top)
  322. {
  323. Node *m;
  324. m = *top;
  325. (*top) = (*top)->next;
  326. return m;
  327. }
  328.  
  329. void stergere_stiva(Node **top)
  330. {
  331. Node *p;
  332. while ((*top) != NULL)
  333. {
  334. p = *top;
  335. *top = (*top)->next;
  336. free(p);
  337. }
  338. }
  339.  
  340. void calculare_scor(Queue *q, Node **top_winners, FILE **f)
  341. {
  342. int suma1 = 0, suma2 = 0, i, j;
  343. fprintf(*f, "\n%s %d ----- %s %d\n", q->front->name, q->front->global_score, q->rear->name, q->rear->global_score);
  344. for (i = 0; i < q->front->nr_players; i++)
  345. for (j = 0; j < q->rear->nr_players; j++)
  346. {
  347. 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);
  348. if (q->front->players[i].score > q->rear->players[j].score)
  349. {
  350. q->front->players[i].score += 5;
  351. suma1 += 3;
  352. }
  353. else if (q->front->players[i].score < q->rear->players[j].score)
  354. {
  355. q->rear->players[j].score += 5;
  356. suma2 += 3;
  357. }
  358. else
  359. {
  360. q->front->players[i].score += 2;
  361. suma1 += 1;
  362. q->rear->players[j].score += 2;
  363. suma2 += 1;
  364. }
  365. }
  366. q->front->global_score += suma1;
  367. q->rear->global_score += suma2;
  368.  
  369. if (suma1 > suma2)
  370. {
  371. push_stack(&(*top_winners), q->front);
  372. }
  373. else
  374. {
  375. push_stack(&(*top_winners), q->rear);
  376. }
  377. }
  378.  
  379. void switch_stacks(Node **top, Node **top_winners)
  380. {
  381. Node *curr = *top_winners;
  382. Node *aux = NULL;
  383. while (curr != NULL)
  384. {
  385. push_stack(&(*top), curr);
  386. aux = curr;
  387. curr = curr->next;
  388. free(aux);
  389. }
  390. }
  391.  
  392. void show_winners(Node *top_winners, FILE **f3)
  393. {
  394. Node *curr = top_winners;
  395. fprintf(*f3, "=== WINNER ===\n");
  396. while (curr != NULL)
  397. {
  398. fprintf(*f3, "%s --- %d\n", curr->name, curr->global_score);
  399. curr = curr->next;
  400. }
  401. }
  402.  
  403. void concurs(Node *top, Node **top_winners, int nr_teams, FILE **f3)
  404. {
  405. int i, j = 0,k = nr_teams;
  406. Node *aux;
  407. Queue *q = NULL;
  408. for (i = 0; k % 2 == 0; i++)
  409. {
  410. aux = top;
  411. while (!isEmpty(aux))
  412. {
  413. fprintf(*f3, "====== ETAPA %d ======\n", j++);
  414. q = creare_coada();
  415. if(!isEmpty(aux))
  416. q->front = pop(&aux);
  417. if(!isEmpty(aux))
  418. q->rear = pop(&aux);
  419. calculare_scor(q, &(*top_winners), &(*f3));
  420. free(q);
  421. }
  422. show_winners(*top_winners, &(*f3));
  423. stergere_stiva(&top);
  424. top = NULL;
  425. switch_stacks(&top, &(*top_winners));
  426. k = k/2;
  427. }
  428. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement