Bac informatică 2024 Varianta 3, rezolvată

Lucrarea „2024 Varianta 3” de la Bacalaureatul la informatică, specializarea Mate-Info, limbajul C/C++: 3 subiecte, 90 de puncte și 3 ore de lucru la examen. Sub fiecare exercițiu ai răspunsul și explicația, închise până le deschizi, ca să încerci întâi singur.

Enunțurile sunt cele oficiale, publicate de Ministerul Educației pe subiecte.edu.ro. Răspunsurile și explicațiile sunt scrise de subac.

Subiectul I20 de puncte

  1. Exercițiul 14p

    Indicați expresia C/C++ care are valoarea 1 dacă și numai dacă numerele memorate în variabilele întregi x și y sunt pare.

    • a)x%2==0 && (y+1)%2!=0
    • b)(x-y)%2==0
    • c)(x+y)%2==0
    • d)x%2==y%2
    Arată răspunsul și explicația

    Răspuns corect: a) x%2==0 && (y+1)%2!=0

    Un număr este par când restul împărțirii lui la 2 este 0. x%2==0 spune că x este par, iar (y+1)%2!=0 spune că y+1 este impar, adică y este par. Legate cu &&, cele două cer ca ambele numere să fie pare: varianta a).

    b), c) și d) sunt adevărate ori de câte ori x și y au aceeași paritate, deci și când amândouă sunt impare (de exemplu 1 și 3).

  2. Exercițiul 24p

    Subprogramul f este definit alăturat.

    Indicați ce se afișează în urma apelului de mai jos.

    f(2020,0);

    void f(int x, int y)
    { if (x<10) cout<<x;  |  printf("%d",x);
      else
      { f(x/10,y+1);
        cout<<x%10; |  printf("%d",x%10);
      }
      cout<<y; |  printf("%d",y);
    }
    • a)23020
    • b)2022100
    • c)02023210
    • d)23022100
    Arată răspunsul și explicația

    Răspuns corect: d) 23022100

    Pentru x≥10, f(x,y) îl apelează întâi pe f(x/10,y+1) și abia apoi afișează ultima cifră a lui x; la sfârșit, în orice caz, afișează y.

    f(2,3) afișează 2, apoi 3. Revenind, f(20,2) afișează 0 și 2, f(202,1) afișează 2 și 1, iar f(2020,0) afișează 0 și 0. În ordine: 23022100.

  3. Exercițiul 34p

    Utilizând metoda backtracking se generează toate permutările elementelor mulțimii ordonate astfel: {1, 2, 3, 4, 5, 6}; pentru fiecare permutare, pe primele trei poziții sunt doar valori pare, iar pe ultimele trei poziții sunt doar valori impare. Primele șase permutări generate sunt, în această ordine:

    1. (2, 4, 6, 1, 3, 5)
    2. (2, 4, 6, 1, 5, 3)
    3. (2, 4, 6, 3, 1, 5)
    4. (2, 4, 6, 3, 5, 1)
    5. (2, 4, 6, 5, 1, 3)
    6. (2, 4, 6, 5, 3, 1)

    Indicați a șaptea permutare generată.

    • a)(4,2,6,1,5,3)
    • b)(4,2,6,1,3,5)
    • c)(2,6,4,1,3,5)
    • d)(2,4,6,5,3,2)
    Arată răspunsul și explicația

    Răspuns corect: c) (2,6,4,1,3,5)

    Permutările se generează în ordine lexicografică. Primele șase au prefixul (2,4,6) și cuprind toate ordinile valorilor impare pe ultimele trei poziții, iar (2,4,6,5,3,1) este ultima dintre ele.

    Urmează cel mai mic prefix cu trei valori pare de după (2,4,6): (2,6,4), completat cu cea mai mică ordine a valorilor impare, (1,3,5): (2,6,4,1,3,5). a) și b) încep cu 4, deci vin mai târziu, iar d) conține de două ori valoarea 2.

  4. Exercițiul 44p

    Variabila x memorează, pentru fiecare dintre cele 20 de sortimente de ciocolată, următoarele date: tipul (litera N pentru ciocolată neagră și litera L pentru ciocolată cu lapte) și prețul produsului.

    Indicați o expresie a cărei valoare este egală cu tipul celui de al 11-lea sortiment de ciocolată.

    struct ciocolata
           { char tip;
             float pret;
           }x[20];
    • a)x.ciocolata[10].tip
    • b)x.tip[10]
    • c)x[10].ciocolata.tip
    • d)x[10].tip
    Arată răspunsul și explicația

    Răspuns corect: d) x[10].tip

    x este un tablou de structuri, iar al 11-lea sortiment este x[10], fiindcă numerotarea începe de la 0. Tipul lui este câmpul tip: x[10].tip.

    a) și c) folosesc numele tipului, ciocolata, ca și cum ar fi un câmp, iar b) îl tratează pe tip ca pe un tablou.

  5. Exercițiul 54p

    Într-un graf neorientat, cu 10 muchii, două noduri au gradul 0, șase noduri au grade impare, iar celelalte noduri au grade pare, nenule.

    Indicați numărul maxim de noduri ale grafului.

    • a)17
    • b)15
    • c)12
    • d)10
    Arată răspunsul și explicația

    Răspuns corect: b) 15

    Suma gradelor tuturor nodurilor este dublul numărului de muchii, 20. Ca graful să aibă cât mai multe noduri, fiecare nod trebuie să consume cât mai puțin din această sumă: nodurile cu grad impar câte 1, iar cele cu grad par nenul câte 2.

    Cele șase noduri de grad impar folosesc 6, iar cei 14 rămași ajung pentru 7 noduri de grad 2. Cu cele două noduri izolate, graful are 2 + 6 + 7 = 15 noduri. Un astfel de graf există: cele 7 noduri de grad 2 formează un ciclu (7 muchii), iar cele 6 de grad 1 sunt legate două câte două (3 muchii).

Subiectul al II-lea40 de puncte

  1. Exercițiul 1.a6p

    Algoritmul alăturat este reprezentat în pseudocod. S-a notat cu [c] partea întreagă a numărului real c.

    Scrieți valoarea afișată dacă se citesc, în această ordine, numerele 5, 15, 27, 10, 1, 17.

     citește n
       (număr natural nenul)
     p←1
    ┌pentru i←1,n execută
    │ citește x
    │  (număr natural)
    │┌repetă
    ││ x←[x/3]
    │└până când x≤3
    │┌dacă x≠0 atunci
    ││ p←p*x
    │└■
    └■
    scrie p
    Arată răspunsul și explicația

    Răspunsul din barem: 9

    9
    
    Fiecare număr citit se împarte la 3 (cu partea întreagă) până ajunge la cel mult 3, iar valoarea rămasă, dacă nu e 0, se înmulțește în p.
    15 → 5 → 1; 27 → 9 → 3; 10 → 3; 1 → 0 (nu se înmulțește); 17 → 5 → 1. Produsul este 1 · 3 · 3 · 1 = 9.
  2. Exercițiul 1.b6p

    Algoritmul alăturat este reprezentat în pseudocod. S-a notat cu [c] partea întreagă a numărului real c.

    Dacă pentru n se citește valoarea 2, scrieți un set de numere distincte din intervalul [0,103] care pot fi citite în continuare, astfel încât, în urma executării algoritmului, să se afișeze valoarea 4.

     citește n
       (număr natural nenul)
     p←1
    ┌pentru i←1,n execută
    │ citește x
    │  (număr natural)
    │┌repetă
    ││ x←[x/3]
    │└până când x≤3
    │┌dacă x≠0 atunci
    ││ p←p*x
    │└■
    └■
    scrie p
    Arată răspunsul și explicația
    Exemplu: 6 20
    
    Pentru n=2 se citesc două numere, iar produsul valorilor rămase trebuie să fie 4. Valoarea rămasă este cel mult 3, deci singura posibilitate este ca ambele numere să se reducă la 2.
    Un număr se reduce la 2 dacă, după împărțiri repetate la 3, ajunge în intervalul [6,8] (care dă 2), adică dacă aparține unui interval de forma [2·3^k, 3^(k+1)), cu k ≥ 1: [6,8], [18,26], [54,80], [162,242], [486,728].
  3. Exercițiul 1.c10p

    Algoritmul alăturat este reprezentat în pseudocod. S-a notat cu [c] partea întreagă a numărului real c.

    Scrieți programul C/C++ corespunzător algoritmului dat.

     citește n
       (număr natural nenul)
     p←1
    ┌pentru i←1,n execută
    │ citește x
    │  (număr natural)
    │┌repetă
    ││ x←[x/3]
    │└până când x≤3
    │┌dacă x≠0 atunci
    ││ p←p*x
    │└■
    └■
    scrie p
    Arată răspunsul și explicația
    #include <iostream>
    using namespace std;
    
    int main()
    {
        int n, p = 1, i, x;
        cin >> n;
        for (i = 1; i <= n; i++)
        {
            cin >> x;
            do
            {
                x = x / 3;
            } while (x > 3);
            if (x != 0) p = p * x;
        }
        cout << p;
        return 0;
    }
    
    pentru i←1,n execută devine for (i = 1; i <= n; i++). repetă…până când x≤3 devine do…while cu condiția negată, x > 3, iar [x/3] este împărțirea întreagă din C/C++.
  4. Exercițiul 1.d6p

    Algoritmul alăturat este reprezentat în pseudocod. S-a notat cu [c] partea întreagă a numărului real c.

    Scrieți în pseudocod un algoritm echivalent cu cel dat, înlocuind adecvat structura pentru...execută cu o structură repetitivă de tip cât timp...execută.

     citește n
       (număr natural nenul)
     p←1
    ┌pentru i←1,n execută
    │ citește x
    │  (număr natural)
    │┌repetă
    ││ x←[x/3]
    │└până când x≤3
    │┌dacă x≠0 atunci
    ││ p←p*x
    │└■
    └■
    scrie p
    Arată răspunsul și explicația
    citește n (număr natural nenul)
    p←1
    i←1
    ┌cât timp i≤n execută
    │ citește x (număr natural)
    │┌repetă
    ││ x←[x/3]
    │└până când x≤3
    │┌dacă x≠0 atunci
    ││ p←p*x
    │└■
    │ i←i+1
    └■
    scrie p
    
    Cu cât timp, contorul se gestionează explicit: i primește valoarea inițială 1 înainte de buclă, se continuă cât timp i≤n, iar i←i+1 se face la sfârșitul corpului.
  5. Exercițiul 26p

    Un arbore cu 8 noduri, numerotate de la 1 la 8, este reprezentat prin vectorul de „tați”: (3, 0, 2, 5, 2, 5, 1, 5). Enumerați, în ordinea parcurgerii lor, nodurile celui mai lung lanț elementar care are extremitatea inițială în rădăcină.

    Arată răspunsul și explicația

    Răspunsul din barem: 2,3,1,7

    2,3,1,7
    
    Rădăcina este nodul 2, singurul cu tatăl 0. Fiii fiecărui nod: 2 are fiii 3 și 5, 3 are fiul 1, 1 are fiul 7, iar 5 are fiii 4, 6 și 8.
    Cel mai lung lanț care pornește din rădăcină coboară până la cea mai adâncă frunză: 2, 3, 1, 7 are lungimea 3, iar lanțurile prin 5 (de exemplu 2, 5, 4) au lungimea 2.
  6. Exercițiul 36p

    Variabilele i și j sunt de tip întreg, iar variabila a memorează un tablou bidimensional cu 9 linii și 9 coloane, numerotate începând de la 0, având inițial toate elementele nule.

    Scrieți secvența de instrucțiuni de mai jos, înlocuind punctele de suspensie cu instrucțiuni adecvate, dintre care cel mult patru de atribuire, astfel încât, în urma executării secvenței obținute, variabila a să memoreze tabloul alăturat.

    for(i=0;i<9;i++)
      for(j=0;j<9;j++)
        ..................
    Figura din enunț
    Arată răspunsul și explicația
    for(i=0;i<9;i++)
      for(j=0;j<9;j++)
        if(i+j<=3 || i+j>=13) a[i][j]=4;
        else a[i][j]=2;
    
    Pe fiecare diagonală paralelă cu cea secundară suma indicilor i+j este constantă. Valorile 4 ocupă colțul din stânga-sus, unde i+j ≤ 3, și colțul din dreapta-jos, unde i+j ≥ 13; toate celelalte elemente sunt 2. Sunt două atribuiri, sub limita de patru.

Subiectul al III-lea30 de puncte

  1. Exercițiul 110p

    Un număr natural se numește major impar dacă suma divizorilor săi proprii impari este strict mai mare decât suma divizorilor săi proprii pari. Divizorii proprii ai unui număr sunt divizorii săi naturali diferiți de 1 și de el însuși.

    Exemplu: 18 este număr major impar (divizorii săi proprii pari sunt 2, 6, cei impari 3, 9, iar 3+9>2+6). Subprogramul majImp are doi parametri, a și b, prin care primește câte un număr natural (2≤a≤b≤104). Subprogramul returnează cel mai mic număr major impar din intervalul [a,b], sau valoarea 0, dacă în interval nu există un astfel de număr. Scrieți în C/C++ definiția completă a subprogramului.

    Exemplu: dacă a=16, b=30, atunci subprogramul returnează 18.

    Arată răspunsul și explicația
    int majImp(int a, int b)
    {
        int n, d, si, sp;
        for (n = a; n <= b; n++)
        {
            si = 0;
            sp = 0;
            for (d = 2; d <= n / 2; d++)
                if (n % d == 0)
                {
                    if (d % 2 == 1) si = si + d;
                    else sp = sp + d;
                }
            if (si > sp) return n;
        }
        return 0;
    }
    
    Numerele din interval se verifică în ordine crescătoare, deci primul număr major impar găsit este și cel mai mic, și se returnează imediat. Pentru fiecare n se adună separat divizorii proprii impari (si) și pari (sp); un divizor propriu este cel mult n/2, de aceea d merge până acolo.
    Dacă niciun număr nu are proprietatea, bucla se termină și se returnează 0.
  2. Exercițiul 210p

    Într-un text, de cel mult 100 de caractere, cuvintele sunt formate din litere ale alfabetului englez și sunt separate prin câte un spațiu. Textul are cel puțin două cuvinte.

    Scrieți un program C/C++ care citește de la tastatură un text de tipul precizat mai sus și afișează pe ecran mesajul DA și un număr natural n, separate printr-un spațiu, dacă toate cuvintele din text au câte n litere, sau mesajul NU în cazul în care nu toate cuvintele au același număr de litere.

    Exemplu: dacă textul citit este Ana are cel mai bun mar se afișează pe ecran DA 3 iar dacă textul citit este Ana are cel mai dulce mar se afișează pe ecran NU

    Arată răspunsul și explicația
    #include <iostream>
    #include <cstring>
    using namespace std;
    
    int main()
    {
        char s[101], *p;
        int lung = -1, ok = 1;
        cin.getline(s, 101);
        p = strtok(s, " ");
        while (p != NULL)
        {
            if (lung == -1) lung = strlen(p);
            else if ((int)strlen(p) != lung) ok = 0;
            p = strtok(NULL, " ");
        }
        if (ok == 1) cout << "DA " << lung;
        else cout << "NU";
        return 0;
    }
    
    Textul se desparte în cuvinte cu strtok. Lungimea primului cuvânt se reține în lung, iar fiecare cuvânt următor se compară cu ea; dacă unul are altă lungime, ok devine 0. La final se afișează DA și lungimea comună sau NU.
  3. Exercițiul 3.a2p

    De-a lungul unui traseu montan este utilizată o succesiune de marcaje turistice, care trebuie urmate în acea ordine. Pentru fiecare marcaj se cunoaște cota (înălțimea, măsurată în metri) la care este plasat. Numim scară într-un traseu o secvență de marcaje aflate pe poziții consecutive în cadrul traseului, care au drept cote numere consecutive, ordonate strict crescător. O scară este formată din cel puțin două marcaje, iar lungimea acesteia este egală cu numărul de marcaje care o compun.

    Fișierul bac.txt conține un șir de cel mult 106 numere naturale din intervalul [10,104], separate prin câte un spațiu, reprezentând cotele marcajelor turistice din cadrul unui traseu, în ordinea în care se succed în acesta. Se cere să se afișeze pe ecran, separate prin câte un spațiu, în ordine strict crescătoare, cotele corespunzătoare marcajelor unei scări de lungime maximă pe acest traseu. Dacă în cadrul traseului există mai multe astfel de scări, se afișează doar cotele corespunzătoare marcajelor uneia dintre ele, iar dacă nu există nicio scară, pe ecran se afișează mesajul nu exista. Proiectați un algoritm eficient din punctul de vedere al timpului de executare și al spațiului de memorie utilizat.

    Exemplu: dacă fișierul conține numerele 500 600 601 405 569 570 700 701 625 626 627 520 atunci pe ecran se afișează 625 626 627

    Descrieți în limbaj natural algoritmul proiectat, justificând eficiența acestuia.

    Arată răspunsul și explicația
    Cotele se citesc pe rând, fără să fie memorate. Se păstrează ultima cotă citită, lungimea scării curente (numărul de marcaje consecutive cu cote consecutive, terminată în cota curentă), precum și lungimea celei mai lungi scări găsite și ultima ei cotă.
    
    Pentru fiecare cotă x: dacă x este cu 1 mai mare decât cota anterioară, scara curentă crește cu un marcaj; altfel începe o scară nouă, de lungime 1. Dacă scara curentă devine mai lungă decât cea mai lungă găsită, se rețin lungimea ei și cota x. La final, dacă cea mai lungă scară are mai puțin de 2 marcaje, se afișează nu exista; altfel cotele ei sunt numerele consecutive care se termină în ultima cotă reținută, deci se pot afișa fără să fi fost memorate.
    
    Eficiență: fiecare cotă se prelucrează o singură dată, în timp constant, deci algoritmul este liniar în numărul de valori din fișier. Se folosesc doar câteva variabile simple, fără tablou, deci memoria este constantă.
  4. Exercițiul 3.b8p

    De-a lungul unui traseu montan este utilizată o succesiune de marcaje turistice, care trebuie urmate în acea ordine. Pentru fiecare marcaj se cunoaște cota (înălțimea, măsurată în metri) la care este plasat. Numim scară într-un traseu o secvență de marcaje aflate pe poziții consecutive în cadrul traseului, care au drept cote numere consecutive, ordonate strict crescător. O scară este formată din cel puțin două marcaje, iar lungimea acesteia este egală cu numărul de marcaje care o compun.

    Fișierul bac.txt conține un șir de cel mult 106 numere naturale din intervalul [10,104], separate prin câte un spațiu, reprezentând cotele marcajelor turistice din cadrul unui traseu, în ordinea în care se succed în acesta. Se cere să se afișeze pe ecran, separate prin câte un spațiu, în ordine strict crescătoare, cotele corespunzătoare marcajelor unei scări de lungime maximă pe acest traseu. Dacă în cadrul traseului există mai multe astfel de scări, se afișează doar cotele corespunzătoare marcajelor uneia dintre ele, iar dacă nu există nicio scară, pe ecran se afișează mesajul nu exista. Proiectați un algoritm eficient din punctul de vedere al timpului de executare și al spațiului de memorie utilizat.

    Exemplu: dacă fișierul conține numerele 500 600 601 405 569 570 700 701 625 626 627 520 atunci pe ecran se afișează 625 626 627

    Scrieți programul C/C++ corespunzător algoritmului proiectat.

    Arată răspunsul și explicația
    #include <fstream>
    #include <iostream>
    using namespace std;
    
    int main()
    {
        ifstream fin("bac.txt");
        int x, ult = -1, lg = 0, lgMax = 0, ultMax = 0, i;
        while (fin >> x)
        {
            if (x == ult + 1) lg++;
            else lg = 1;
            ult = x;
            if (lg > lgMax)
            {
                lgMax = lg;
                ultMax = x;
            }
        }
        fin.close();
        if (lgMax < 2) cout << "nu exista";
        else
            for (i = ultMax - lgMax + 1; i <= ultMax; i++)
                cout << i << ' ';
        return 0;
    }
    
    Programul face pașii de la 3.a. ult pornește de la -1, astfel încât prima cotă (cel puțin 10) începe sigur o scară nouă. Cotele scării maxime se reconstruiesc din ultima ei cotă și din lungime.

Vrei să vezi cât ai lua?

În test ai cronometrul de la examen, codul tău se compilează pe loc, iar la final primești nota.

Rezolv-o cu timpul de la examen