Bac informatică 2026 Varianta 4, rezolvată

Lucrarea „2026 Varianta 4” 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++ a cărei valoare este egală cu 26.

    • a)(2026-26)/100
    • b)2026/100
    • c)(2026-26)%100
    • d)2026%100
    Arată răspunsul și explicația

    Răspuns corect: d) 2026%100

    % dă restul împărțirii, iar 2026 = 20·100 + 26, deci 2026%100 este 26. Celelalte trei nu pot: (2026-26)/100 și 2026/100 dau amândouă 20 (împărțirea a două numere întregi trunchiază), iar (2026-26)%100 este 0, fiindcă 2000 se împarte exact la 100.

  2. Exercițiul 24p

    Subprogramul f este definit alăturat.

    Indicați valoarea f(1,10).

    int f(int n,int m)
    { if(n>=m) return 0;
      else return 1+f(n+1,m-2);
    }
    • a)1
    • b)3
    • c)5
    • d)7
    Arată răspunsul și explicația

    Răspuns corect: b) 3

    Fiecare apel adaugă 1 și se autoapelează cu n mai mare cu 1 și m mai mic cu 2, deci distanța m-n scade cu 3 de fiecare dată: 9 → 6 → 3 → 0. Recursivitatea se oprește când n>=m. Desfășurat: f(1,10) = 1+f(2,8) = 1+1+f(3,6) = 1+1+1+f(4,4) = 3+0 = 3.

  3. Exercițiul 34p

    O agenție de turism pune la dispoziție pachete de vacanță cu câte trei destinații, în ordinea următoare: una pe Clisura Dunării, una la munte și una pe litoral. Utilizând metoda backtracking, se generează toate pachetele formate cu destinații din mulțimile ordonate astfel {Dubova, Eșelnița, Șvinița} pentru Clisura Dunării, {Bușteni, Păltiniș, Predeal}, pentru munte și {Venus, Neptun, Olimp} pentru litoral. Două soluții diferă prin cel puțin o destinație de un anumit tip. Primele cinci pachete generate sunt, în această ordine:

    1. (Dubova, Bușteni, Venus)
    2. (Dubova, Bușteni, Neptun)
    3. (Dubova, Bușteni, Olimp)
    4. (Dubova, Păltiniș, Venus)
    5. (Dubova, Păltiniș, Neptun)

    Indicați pachetul generat imediat înainte de (Șvinița, Bușteni, Venus).

    • a)(Eșelnița, Bușteni, Venus)
    • b)(Eșelnița, Predeal, Olimp)
    • c)(Svinița, Păltiniș, Olimp)
    • d)(Svinița, Predeal, Olimp)
    Arată răspunsul și explicația

    Răspuns corect: b) (Eșelnița, Predeal, Olimp)

    (Șvinița, Bușteni, Venus) este primul pachet care începe cu Șvinița, deci înaintea lui vine ultimul pachet care începe cu Eșelnița — adică cel cu ultima destinație din fiecare dintre celelalte două mulțimi: (Eșelnița, Predeal, Olimp). Varianta a) este dimpotrivă primul pachet cu Eșelnița, iar c) și d) încep cu Șvinița, deci vin după, nu înainte.

  4. Exercițiul 44p

    Un graf orientat cu 4 vârfuri, numerotate de la 1 la 4, este reprezentat prin matricea de adiacență alăturată.

    Indicați un circuit elementar în acest graf.

    0110
    1010
    0001
    1100
    • a)1, 2, 1, 3, 4, 1
    • b)1, 2, 3, 4
    • c)1, 3, 4, 2, 1
    • d)1, 4, 3, 2, 1
    Arată răspunsul și explicația

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

    Un circuit elementar pornește și se închide în același vârf, fără să treacă de două ori prin altul. 1, 3, 4, 2, 1 folosește arcele 1→3, 3→4, 4→2 și 2→1, toate cu 1 în matrice. În a) vârful 1 apare și la mijloc, deci nu e elementar; b) nu se închide; d) ar avea nevoie de arcul 1→4, iar în matrice pe linia 1, coloana 4 este 0.

  5. Exercițiul 54p

    O companie de logistică are o rețea formată din 12 centre, numerotate de la 1 la 12, între care există comunicații bidirecționale, astfel: între 1 și 2, între 1 și 3, între 2 și 3, între 2 și 4, între 3 și 5, între 4 și 5, între 4 și 6, între 5 și 6, între 6 și 7, între 7 și 8, între 7 și 9, între 8 și 9, între 9 și 10, între 10 și 11, între 10 și 12, între 11 și 12. Rețeaua este modelată ca un graf neorientat, în care nodurile reprezintă centrele, iar muchiile reprezintă comunicațiile dintre acestea.

    Indicați numărul minim de muchii care trebuie eliminate, astfel încât graful parțial obținut să fie format din trei componente conexe, fiecare cu câte 4 noduri.

    • a)2
    • b)4
    • c)5
    • d)7
    Arată răspunsul și explicația

    Răspuns corect: c) 5

    Rețeaua e un lanț de patru triunghiuri: {1,2,3} — {4,5,6} — {7,8,9} — {10,11,12}, legate prin muchiile 2-4 și 3-5, apoi 6-7, apoi 9-10. Centrele 10, 11 și 12 ajung la restul rețelei doar prin 9, deci una dintre componente trebuie să fie {9,10,11,12} — asta cere eliminarea muchiilor 7-9 și 8-9. Rămân opt centre de împărțit în două grupe de patru: muți un centru din {4,5,6} lângă triunghiul {1,2,3}, de exemplu {1,2,3,4} și {5,6,7,8}, ceea ce taie 3-5, 4-5 și 4-6. În total 2 + 3 = 5 muchii.

Subiectul al II-lea40 de puncte

  1. Exercițiul 1.a6p

    Algoritmul alăturat este reprezentat în pseudocod.

    S-a notat cu a%b restul împărțirii numărului natural a la numărul natural nenul b și cu [c] partea întreagă a numărului real c.

    Scrieți valoarea afișată în urma executării algoritmului dacă se citește numărul 2600.

     citește n
        (număr natural nenul)
     nr←0; d←2
    ┌cât timp d*d≤n execută
    │ p←0
    │┌cât timp n%d=0 execută
    ││ p←1; n←[n/d]
    │└■
    │ nr←nr+p; d←d+1
    └■
    ┌dacă n≠1 atunci
    │ nr←nr+1
    └■
    scrie nr
    Arată răspunsul și explicația

    Răspunsul din barem: 3

    3
    
    Algoritmul numără câți factori primi DISTINCȚI are n, fiindcă p devine 1 o singură dată pentru fiecare divizor, oricâte împărțiri s-ar face.
    2600 = 2^3 · 5^2 · 13, deci trei: 2, 5 și 13.
    
    Pas cu pas: d=2 împarte de trei ori (n ajunge 325) și adaugă 1 la nr; d=3 și d=4 nu divid 325; d=5 împarte de două ori (n ajunge 13) și mai adaugă 1.
    Bucla se oprește fiindcă 6·6 > 13. Cum n a rămas 13 ≠ 1, ultima decizie mai adaugă 1. Se afișează 3.
  2. Exercițiul 1.b6p

    Algoritmul alăturat este reprezentat în pseudocod.

    S-a notat cu a%b restul împărțirii numărului natural a la numărul natural nenul b și cu [c] partea întreagă a numărului real c.

    Scrieți două numere din intervalul [10,99] care pot fi citite, astfel încât, pentru fiecare dintre acestea, în urma executării algoritmului să se afișeze 1.

     citește n
        (număr natural nenul)
     nr←0; d←2
    ┌cât timp d*d≤n execută
    │ p←0
    │┌cât timp n%d=0 execută
    ││ p←1; n←[n/d]
    │└■
    │ nr←nr+p; d←d+1
    └■
    ┌dacă n≠1 atunci
    │ nr←nr+1
    └■
    scrie nr
    Arată răspunsul și explicația
    Exemplu: 16 și 97
    
    Se afișează 1 exact pentru numerele cu un singur factor prim distinct, adică pentru puterile unui număr prim. Din intervalul [10,99]: 16=2^4, 32, 64, 27=3^3, 81, 25=5^2, 49=7^2, precum și orice număr prim de două cifre (11, 13, 17, …, 97).
    
    Pentru 16: d=2 împarte de patru ori, nr devine 1, iar n ajunge 1, deci ultima decizie nu mai adaugă nimic.
    Pentru 97: niciun d cu d·d ≤ 97 nu îl divide, nr rămâne 0, dar n = 97 ≠ 1, deci ultima decizie îl face 1.
  3. Exercițiul 1.c10p

    Algoritmul alăturat este reprezentat în pseudocod.

    S-a notat cu a%b restul împărțirii numărului natural a la numărul natural nenul b și 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)
     nr←0; d←2
    ┌cât timp d*d≤n execută
    │ p←0
    │┌cât timp n%d=0 execută
    ││ p←1; n←[n/d]
    │└■
    │ nr←nr+p; d←d+1
    └■
    ┌dacă n≠1 atunci
    │ nr←nr+1
    └■
    scrie nr
    Arată răspunsul și explicația
    #include <iostream>
    using namespace std;
    
    int main()
    {
        int n, nr = 0, d = 2, p;
        cin >> n;
        while (d * d <= n)
        {
            p = 0;
            while (n % d == 0)
            {
                p = 1;
                n = n / d;
            }
            nr = nr + p;
            d = d + 1;
        }
        if (n != 1) nr = nr + 1;
        cout << nr;
        return 0;
    }
    
    cât timp se scrie while, iar [n/d] nu cere nimic special: împărțirea a două numere întregi în C/C++ dă deja câtul. Condiția d*d<=n folosește n așa cum e în acel moment — n se micșorează în buclă, exact ca în pseudocod, așa că se transcrie ca atare.
  4. Exercițiul 1.d6p

    Algoritmul alăturat este reprezentat în pseudocod.

    S-a notat cu a%b restul împărțirii numărului natural a la numărul natural nenul b și cu [c] partea întreagă a numărului real c.

    Scrieți în pseudocod un algoritm, echivalent cu cel dat, înlocuind a doua structură cât timp...execută cu o structură repetitivă cu test final.

     citește n
        (număr natural nenul)
     nr←0; d←2
    ┌cât timp d*d≤n execută
    │ p←0
    │┌cât timp n%d=0 execută
    ││ p←1; n←[n/d]
    │└■
    │ nr←nr+p; d←d+1
    └■
    ┌dacă n≠1 atunci
    │ nr←nr+1
    └■
    scrie nr
    Arată răspunsul și explicația
    citește n (număr natural nenul)
    nr←0; d←2
    ┌cât timp d*d≤n execută
    │ p←0
    │┌dacă n%d=0 atunci
    ││┌repetă
    │││ p←1; n←[n/d]
    ││└până când n%d≠0
    │└■
    │ nr←nr+p; d←d+1
    └■
    ┌dacă n≠1 atunci
    │ nr←nr+1
    └■
    scrie nr
    
    repetă…până când execută corpul cel puțin o dată, pe când cât timp poate să nu îl execute deloc. De aceea înlocuirea cere în plus o gardă: se intră în repetă numai dacă n%d=0. Condiția de oprire este negata celei de continuare: se repetă cât timp n%d=0, deci se oprește când n%d≠0.
  5. Exercițiul 26p

    Variabilele s și t permit memorarea câte unui șir de maximum 20 de caractere.

    Scrieți valorile afișate în urma executării secvenței C/C++ alăturate.

    strcpy(s,"anatoliana"); strcpy(t,"ana");
    cout<<strlen(s)<<' '; | printf("%d ",strlen(s));
    if(strstr(s,t)==s) cout<<"DA "; | printf("DA ");
    else cout<<"NU "; | printf("NU ");
    if(strcmp(strstr(s+1,t),t)==0) cout<<"DA"; | printf("DA");
    else cout<<"NU"; | printf("NU");
    Arată răspunsul și explicația

    Răspunsul din barem: 10 DA DA

    10 DA DA
    
    strlen(s) numără caracterele din "anatoliana": 10.
    strstr(s,t) caută "ana" în "anatoliana" și o găsește chiar de la început, deci pointerul întors este egal cu s → DA.
    strstr(s+1,t) caută în "natoliana" și găsește "ana" la sfârșit; strcmp compară acel subșir cu "ana" și dă 0 → DA.
  6. Exercițiul 36p

    Variabila s memorează datele înregistrate la un observator astronomic: numărul de stele observate (număr natural din intervalul [10,200]), precum și, pentru fiecare stea, magnitudinea aparentă (număr real) și distanța în ani-lumină față de Pământ (număr natural din intervalul [1,106]).

    Știind că expresiile C/C++ de mai jos au ca valori numărul de stele observate, magnitudinea aparentă a primei stele și distanța în ani-lumină a acesteia față de Pământ, scrieți definiția unei structuri cu eticheta observator, care permite memorarea datelor precizate, și declarați corespunzător variabila s.

    s.numar s.stea[0].magnitudine s.stea[0].distanta
    Arată răspunsul și explicația
    struct astru
    {   float magnitudine;
        int distanta;
    };
    
    struct observator
    {   int numar;
        astru stea[200];
    };
    
    observator s;
    
    Expresiile din enunț spun exact ce câmpuri sunt necesare: s.numar e un
    întreg, iar s.stea[0] e la rândul lui o structură, cu magnitudine (real) și
    distanta (întreg). Tabloul stea are 200 de elemente, fiindcă se observă cel
    mult 200 de stele, iar distanța de cel mult 10^6 ani-lumină încape într-un
    int.

Subiectul al III-lea30 de puncte

  1. Exercițiul 110p

    La o paradă de modă se prezintă modele de rochii și costume, iar ordinea acestora este dată ca o succesiune de cifre, cele impare reprezentând rochii, iar cele pare costume; în prezentare este inclus cel puțin un costum.

    Subprogramul moda are doi parametri:

    n, prin care primește un număr natural din intervalul [0,109], ale cărui cifre, de la stânga la dreapta, corespund modelelor, în ordinea prezentării lor;

    pc, prin care furnizează numărul de ordine al primului costum prezentat.

    Scrieți definiția completă a subprogramului C/C++.

    Exemplu: dacă n=576798 sau n=5700, atunci pc=3.

    Arată răspunsul și explicația
    void moda(int n, int &pc)
    {
        int k = 0, ultimaPara = 0;
        do
        {
            k++;
            if (n % 10 % 2 == 0) ultimaPara = k;
            n = n / 10;
        } while (n != 0);
        pc = k - ultimaPara + 1;
    }
    
    Cifrele se parcurg de la dreapta la stânga și se numără (k). La fiecare cifră pară se reține poziția ei, numărată de la dreapta; ultima reținută este cifra pară cea mai din stânga, adică primul costum. Numărată de la stânga, poziția ei este k - ultimaPara + 1.
    Structura do…while tratează și n = 0 (o singură cifră, 0, pară) și zerourile de la final: pentru 5700 cifrele citite sunt 0, 0, 7, 5, deci ultimaPara = 2, k = 4 și pc = 3.
  2. Exercițiul 210p

    Scrieți un program C/C++ care citește de la tastatură două numere naturale din intervalul [2,50], m și n, și elementele unui tablou bidimensional cu m linii și n coloane, numere naturale din intervalul [0,102]. Programul transformă tabloul în memorie, interschimbând, pentru fiecare coloană, elementul său de valoare minimă cu primul element al coloanei, dacă acest minim este par, sau cu ultimul element al coloanei, dacă acest minim este impar. Dacă pe o coloană sunt mai multe elemente de valoare minimă, se alege doar unul dintre acestea. Tabloul obținut este afișat pe ecran, linie cu linie, de sus în jos, fiecare linie a tabloului pe câte o linie a ecranului, cu elementele parcurse de la stânga la dreapta, separate prin câte un spațiu.

    Exemplu: pentru m=4, n=5 și tabloul alăturat

    Figura din enunț
    Arată răspunsul și explicația
    #include <iostream>
    using namespace std;
    
    int main()
    {
        int m, n, a[50][50], i, j, p, aux;
        cin >> m >> n;
        for (i = 0; i < m; i++)
            for (j = 0; j < n; j++)
                cin >> a[i][j];
        for (j = 0; j < n; j++)
        {
            p = 0;
            for (i = 1; i < m; i++)
                if (a[i][j] < a[p][j]) p = i;
            if (a[p][j] % 2 == 0)
            {
                aux = a[p][j]; a[p][j] = a[0][j]; a[0][j] = aux;
            }
            else
            {
                aux = a[p][j]; a[p][j] = a[m - 1][j]; a[m - 1][j] = aux;
            }
        }
        for (i = 0; i < m; i++)
        {
            for (j = 0; j < n; j++)
                cout << a[i][j] << ' ';
            cout << '\n';
        }
        return 0;
    }
    
    Pentru fiecare coloană se află poziția p a minimului (prima apariție). Dacă minimul e par, se interschimbă cu primul element al coloanei, altfel cu ultimul.
    Când pe o coloană sunt mai multe minime, enunțul acceptă oricare dintre ele, deci pot fi mai multe tablouri corecte — de aceea testele de aici au pe fiecare coloană un singur minim.
  3. Exercițiul 3.a2p

    La o firmă de curierat, în prima lună nu s-a livrat niciun pachet, în cea de-a doua lună s-au livrat 3 pachete, apoi numărul de pachete livrate în fiecare lună a fost egal cu suma dintre numărul de pachete livrate în luna precedentă și dublul valorii absolute a diferenței dintre numărul de pachete livrate în cele două luni precedente, obținând astfel șirul numărului de pachete livrate: 0 3 9 21 45 93 189 381 ....

    Se citesc de la tastatură două numere naturale din intervalul [0,109], reprezentând numărul de pachete livrate de firma de curierat în ultima și respectiv penultima lună, și se cere să se scrie în fișierul bac.txt, în ordine descrescătoare, separate prin câte un spațiu, numărul de pachete livrate în fiecare lună. Proiectați un algoritm eficient din punctul de vedere al timpului de executare și al memoriei utilizate.

    Exemplu: dacă se citesc valorile 189 și 93, fișierul conține numerele: 189 93 45 21 9 3 0

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

    Arată răspunsul și explicația
    Șirul crește, deci termenul următor este a(k) = a(k-1) + 2·(a(k-1) - a(k-2)) = 3·a(k-1) - 2·a(k-2). De aici, termenul dinaintea a două valori consecutive x (ultima) și y (penultima) este z = (3·y - x) / 2.
    
    Se scriu în fișier x și y, apoi, cât timp ultima valoare scrisă (y) nu este 0, se calculează z = (3·y - x) / 2, se scrie z și se mută fereastra: x devine y, y devine z. Primul termen al șirului este 0, deci procesul se oprește exact după ce 0 a fost scris.
    
    Eficiență: fiecare lună se calculează o singură dată, în timp constant, deci timpul este liniar în numărul de luni; se păstrează doar ultimele două valori, deci memoria folosită este constantă, fără niciun tablou.
  4. Exercițiul 3.b8p

    La o firmă de curierat, în prima lună nu s-a livrat niciun pachet, în cea de-a doua lună s-au livrat 3 pachete, apoi numărul de pachete livrate în fiecare lună a fost egal cu suma dintre numărul de pachete livrate în luna precedentă și dublul valorii absolute a diferenței dintre numărul de pachete livrate în cele două luni precedente, obținând astfel șirul numărului de pachete livrate: 0 3 9 21 45 93 189 381 ....

    Se citesc de la tastatură două numere naturale din intervalul [0,109], reprezentând numărul de pachete livrate de firma de curierat în ultima și respectiv penultima lună, și se cere să se scrie în fișierul bac.txt, în ordine descrescătoare, separate prin câte un spațiu, numărul de pachete livrate în fiecare lună. Proiectați un algoritm eficient din punctul de vedere al timpului de executare și al memoriei utilizate.

    Exemplu: dacă se citesc valorile 189 și 93, fișierul conține numerele: 189 93 45 21 9 3 0

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

    Arată răspunsul și explicația
    #include <fstream>
    #include <iostream>
    using namespace std;
    
    int main()
    {
        long long x, y, z;
        cin >> x >> y;
        ofstream fout("bac.txt");
        fout << x << ' ' << y;
        while (y != 0)
        {
            z = (3 * y - x) / 2;
            fout << ' ' << z;
            x = y;
            y = z;
        }
        fout.close();
        return 0;
    }
    
    Valorile ajung până la 10^9, iar 3·y depășește limita tipului int, de aceea se folosește long long. Fișierul se scrie în ordinea cerută, descrescător, fără să fie nevoie de memorarea șirului.

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