Sari la conținut

Bac informatică 2024 Varianta 3, rezolvată

Varianta 3 de la Bacalaureatul la Informatică (Mate-Info, C/C++): conține 3 subiecte (90 de puncte) și are un timp de lucru de 3 ore. Sub fiecare exercițiu găsești răspunsul corect și rezolvarea.

Subiecte oficiale publicate de Ministerul Educației. Rezolvări realizate de subac. Actualizat la .

📌 Despre Varianta 3 din 2024

Varianta 3 din 2024 trece prin expresii logice, recursivitate, backtracking, structuri, grafuri și arbori, matrice, divizori, șiruri de caractere și fișiere. Este o variantă echilibrată, ideală ca test complet.

Subiectul I (20p): 5 grile: o expresie care verifică dacă două numere sunt pare, un subprogram recursiv care afișează cifre și niveluri de apel, o problemă de backtracking cu permutări care au valorile pare pe primele trei poziții, tipul celui de-al 11-lea sortiment dintr-un tablou de structuri ciocolata și numărul maxim de noduri ale unui graf cu 10 muchii și grade date.

Subiectul al II-lea (40p): Un algoritm în pseudocod care împarte repetat fiecare număr citit la 3 și înmulțește valorile rămase, cel mai lung lanț elementar care pornește din rădăcina unui arbore dat prin vectorul de „tați” și o secvență care completează o matrice 9×9 cu 4 și 2, după suma indicilor.

Subiectul al III-lea (30p): Un subprogram cu divizori (majImp, cel mai mic număr „major impar” dintr-un interval), o problemă cu șiruri de caractere care verifică dacă toate cuvintele unui text au aceeași lungime și o problemă de eficiență care caută cea mai lungă „scară” de cote consecutive dintr-un traseu citit din fișierul bac.txt.

⚠️ La ce să fii atent

  • La I.2: Fiecare apel afișează y la final, inclusiv cele care au făcut un apel recursiv. Cifrele lui 2020 apar la întoarcere, fiecare urmată de nivelul ei: 23022100.
  • La I.5: Suma gradelor este 20. Ca să ai cât mai multe noduri, nodurile cu grad impar primesc gradul 1, iar cele cu grad par nenul gradul 2: 6 + 7·2 = 20, deci graful are 2 + 6 + 7 = 15 noduri.
  • La II.1.a: repetă împarte la 3 cel puțin o dată, deci 1 devine 0 și nu se înmulțește, iar 10 se oprește la 3. Produsul este 9.
  • La III.1: Divizorii proprii nu includ 1 și nici numărul însuși. Pentru 18, compari 3 + 9 cu 2 + 6.
  • La III.3: Cotele unei scări sunt numere consecutive, deci fiecare este cu exact 1 mai mare decât cea dinainte. Ține minte doar lungimea celei mai lungi scări și ultima ei cotă: cotele se pot reconstrui la final, fără tablou.

Subiectul I

20 de puncte
  1. Exercițiul 1 4p Expresii și operatori

    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
    Vezi rezolvarea

    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 2 4p Recursivitate

    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
    Vezi rezolvarea

    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 3 4p Backtracking

    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)
    Vezi rezolvarea

    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 4 4p Tipul înregistrare (struct)

    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
    Vezi rezolvarea

    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 5 4p Grafuri neorientate

    Î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
    Vezi rezolvarea

    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-lea

40 de puncte
  1. Exercițiul 1.a 6p Algoritmi în pseudocod

    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
    Vezi rezolvarea

    Răspunsul din barem: 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.b 6p Algoritmi în pseudocod

    Același algoritm ca la 1.a.

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

    Vezi rezolvarea

    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.c 10p Algoritmi în pseudocod

    Același algoritm ca la 1.a.

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

    Vezi rezolvarea
    #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.d 6p Algoritmi în pseudocod

    Același algoritm ca la 1.a.

    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ă.

    Vezi rezolvarea
    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 2 6p Arbori

    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ă.

    Vezi rezolvarea

    Răspunsul din barem: 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 3 6p Tablouri bidimensionale

    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++)
        ..................
    Tablou cu 9 linii și 9 coloane, cu valori 4 și 2. În colțul din stânga sus, valorile 4 formează un triunghi: 4 valori pe prima linie, apoi 3, 2 și 1. În colțul din dreapta jos, un triunghi la fel: o valoare pe linia a șasea, apoi 2, 3 și 4 pe ultima linie. Restul valorilor sunt 2, iar valorile 4 sunt colorate cu gri.
    Vezi rezolvarea
    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-lea

30 de puncte
  1. Exercițiul 1 10p Subprograme

    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≤10^4). 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.

    Vezi rezolvarea
    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 2 10p Șiruri de caractere

    Î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

    Vezi rezolvarea
    #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.a 2p Algoritmi eficienți

    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 10^6 numere naturale din intervalul [10,10^4], 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.

    Vezi rezolvarea

    Timp de executare: O(n) · Memorie: O(1)

    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.b 8p Algoritmi eficienți

    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 10^6 numere naturale din intervalul [10,10^4], 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.

    Vezi rezolvarea
    #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 ce notă ai lua la examen?

Intră în modul simulare: ai cronometru de 3 ore, codul ți se compilează pe loc, iar la final primești nota conform baremului.

Începe simularea3 ore

Ai găsit o problemă sau ai o idee?

Despre ce este vorba?