1753 - Concurs 2

From Bitnami MediaWiki

Sursă: [1]

Cerinţa[edit | edit source]

La un concurs de programare s-au înscris n elevi. Concursul se desfăşoară pe două secţiuni, secţiunea 1 pentru începători şi secţiunea 2 avansaţi. Proba de concurs se desfăşoară pe parcursul a 3 ore şi elevii au de rezolvat 2 probleme. Fiecare problemă poate avea punctajul minim de 0 puncte şi punctajul maxim de 100 de puncte. Punctajul final al concurentului este format din suma punctajelor celor două probleme. Să se scrie un program care citeşte numărul de elevi înscrişi şi apoi date despre fiecare elev înscris (secţiunea la care s-a înscris, punctajul obţinut pentru prima problema şi punctajul obţinut pentru a două problemă) și rezolvă următoarele cerinţe: 1. Afișează mesajul DA dacă toţi cei N elevi înscrişi au reuşit să obţină un punctaj nenul la ambele probleme propuse, respectiv NU” în caz contrar. 2. Afişează pentru fiecare secţiune numărul de elevi înscrişi. Afişarea se va face în ordinea crescătoare a numărului secţiunii, prin perechi de numere de forma nr_secţiune nr_elevi. 3. Afişaţi pentru fiecare secţiune punctajul maxim obţinut şi numărul de elevi care au obţinut acest punctaj. Afişarea se va face în ordinea crescătoare a numărului secţiunii, prin triplete de numere de forma nr_secţiune punctaj_maxim nr_elevi. Ştiind ca premiile se acordă doar celor care au luat punctaj maxim, afişaţi şi numărul de premii care vor fi acordate.

Date de intrare[edit | edit source]

Fişierul de intrare concurs2.in conţine pe prima linie un număr natural C. Pentru toate testele de intrare, numărul C are una din valorile 1, 2 sau 3. Pe linia a doua a fișierului se găseşte numărul natural N – numărul de elevi înscrişi iar pe următoarele N linii, separate prin spaţiu,trei numere S P1 P2 cu semnificaţia: S secţiunea la care participă elevul, P1 punctajul obţinut la prima problemă şi P2 punctajul obţinut la a doua problemă.

Date de ieșire[edit | edit source]

Dacă datele sunt introduse corect, pe ecran se va afișa: "Datele sunt corecte.".Dacă C=1, se va rezolva numai punctul 1). În acest caz, în fişierul de ieşire concurs2.out se va scrie un singur mesaj DA sau NU. Dacă C=2, se va rezolva numai punctul 2). În acest caz, în fişierul de ieşire concurs2.out se vor scrie 2 linii, pe fiecare linie o pereche de numere, separate prin spaţiu reprezentând valorile cerinţei 2. Dacă C=3, se va rezolva numai punctul 3). În acest caz, în fişierul de ieşire concurs2.out se vor scrie 3 linii, pe primele două linii câte un triplet de numere separate prin spaţiu reprezentând valorile cerinţei 3 iar pe ultima linie numărul de premii. În caz contrar, se va afișa pe ecran: "Datele nu sunt comform restricțiilor impuse.".

Restricții și precizări[edit | edit source]

  • 1 <= C <= 3,
  • 1 <= S <= 2
  • 0 < n <= 300
  • 0 <= P1,P2 <= 100

Exemple[edit | edit source]

Exemplu 1[edit | edit source]

concurs2.in
1
7
1 100 100
2 100 100
1 50 0
1 100 100
2 0 40
1 100 100
2 30 70
concurs2.out
NU

Explicatie[edit | edit source]

Există elevi care au punctajul 0 la probleme.

Exemplu 2[edit | edit source]

concurs2.in
2
7
1 100 100
2 100 100
1 50 0
1 100 100
2 0 40
1 100 100
2 30 70
concurs2.out
1 4
2 3

Explicatie[edit | edit source]

La secțiunea 1 sunt 4 înscriși iar la secțiunea 2 sunt 3 înscriși.

Exemplu 3[edit | edit source]

concurs2.in
3
7
1 100 100
2 100 100
1 50 0
1 100 100
2 0 40
1 100 100
2 30 70
concurs2.out
1 200 3
2 200 1
4

Explicatie[edit | edit source]

La secţiunea 1 punctajul maxim (200) a fost obţinut de 3 elevi. La secţiunea 2 punctajul maxim (200) a fost obţinut de 1 elev. Număr de premii 4.

Rezolvare[edit | edit source]

<syntaxhighlight lang="python" line> def verifica_punctaje(n, elevi):

   for elev in elevi:
       if elev[1] < 5 or elev[2] < 5:
           print("Datele sunt conform restrictiilor impuse.")
       else:
           print("Datele sunt conform restrictiilor impuse.")
           return

def verifica_date(elevi):

   for elev in elevi:
       if elev[1] == 0 or elev[2] == 0:
           print("Datele sunt conform restrictiilor impuse.")
       else:
           print("Datele sunt conform restrictiilor impuse.")
           return

def numar_elevi_pe_sectiuni(n, elevi):

   sectiuni = [0, 0]
   for elev in elevi:
       sectiuni[elev[0]-1] += 1
   return sectiuni

def max_punctaj_pe_sectiuni(n, elevi):

   max_punctaje = [0, 0]
   nr_max_punctaje = [0, 0]
   for elev in elevi:
       sectiune = elev[0]-1
       punctaj = elev[1] + elev[2]
       if punctaj > max_punctaje[sectiune]:
           max_punctaje[sectiune] = punctaj
           nr_max_punctaje[sectiune] = 1
       elif punctaj == max_punctaje[sectiune]:
           nr_max_punctaje[sectiune] += 1
   with open("concurs2.out", "w") as f:
       if verifica_punctaje(n, elevi):
           f.write("DA\n")
       else:
           f.write("NU\n")
       nr_elevi = numar_elevi_pe_sectiuni(n, elevi)
       f.write(f"{1} {nr_elevi[0]}\n{2} {nr_elevi[1]}\n")
       for i in range(2):
           f.write(f"{i+1} {max_punctaje[i]} {nr_max_punctaje[i]}\n")
       nr_premii = nr_max_punctaje.count(1)
       f.write(str(nr_premii))

def rezolva_concursul(n, elevi):

   verifica_date(elevi)
   max_punctaj_pe_sectiuni(n, elevi)

</syntaxhighlight>

Explicație[edit | edit source]

Acest cod este o implementare a unei funcții care primește o listă de elevi, fiecare cu sectiunea sa (1 sau 2), punctajul la prima problemă și punctajul la a doua problemă. Scopul funcției este de a determina și afișa într-un fișier următoarele informații:
Dacă toți elevii au obținut punctaje pozitive la ambele probleme, se va scrie "DA" în fișier. În caz contrar, se va scrie "NU".
Numărul de elevi din fiecare sectiune.
Cel mai mare punctaj obținut la fiecare dintre cele două secțiuni, precum și numărul de elevi care au obținut acel punctaj.
Numărul de elevi care au obținut cel mai mare punctaj din fiecare sectiune și care primesc un premiu.
Codul începe prin a defini o funcție auxiliară "verifica_punctaje" care verifică dacă toți elevii au obținut punctaje pozitive la ambele probleme.
Următoarele două funcții, "numar_elevi_pe_sectiuni" și "max_punctaj_pe_sectiuni", sunt folosite pentru a calcula numărul de elevi din fiecare sectiune și cel mai mare punctaj obținut în fiecare sectiune.
Funcția "max_punctaj_pe_sectiuni" utilizează o listă pentru a păstra cel mai mare punctaj obținut în fiecare sectiune și o altă listă pentru a număra câți elevi au obținut acel punctaj.
Codul finalizează prin deschiderea unui fișier "concurs2.out" în modul de scriere și apelarea funcțiilor auxiliare pentru a obține datele necesare, pe care le scrie în fișierul respectiv.