Bac informatică 2023 Model, rezolvată

Lucrarea „2023 Model” 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 două valori pe care le poate avea variabila întreagă x, astfel încât, pentru fiecare dintre acestea, expresia C/C++ alăturată să aibă valoarea 1.

    x%20==x/23
    • a){20, 40}
    • b){20,41}
    • c){40, 62}
    • d){60, 83}
    Arată răspunsul și explicația

    Răspuns corect: b) {20,41}

    Pentru 20: 20%20 este 0, iar 20/23 este 0, deci egalitatea este adevărată. Pentru 41: 41%20 este 1, iar 41/23 este tot 1, deci și ea este adevărată.

    În a) și c), pentru 40 se obțin 0 și 1, iar în d), pentru 60 se obțin 0 și 2.

  2. Exercițiul 24p

    Subprogramul f este definit alăturat.

    Indicați un apel în urma căruia în șirul afișat există două valori egale cu 23.

    void f(int m, int n)
    { cout<<(m+n)/2<<' '; | printf("%d ",(m+n)/2);
      if(m<=n) f(m+1,n-2);
    }
    • a)f(20,23);
    • b)f(20,26);
    • c)f(21,25);
    • d)f(21,27);
    Arată răspunsul și explicația

    Răspuns corect: d) f(21,27);

    Fiecare apel afișează (m+n)/2 și continuă cu m mai mare cu 1 și n mai mic cu 2, cât timp m≤n.

    f(21,27) afișează 24, apoi f(22,25) afișează 23, f(23,23) afișează tot 23, iar f(24,21) afișează 22 și se oprește: două valori egale cu 23. Celelalte apeluri afișează valoarea 23 cel mult o dată.

  3. Exercițiul 34p

    Utilizând metoda backtracking, se generează toate torturile formate din trei straturi de tipuri distincte de cremă din mulțimea {castane, mousse, frișcă, șerbet, ganache}. Ultimul strat este de frișcă sau de ganache, iar aceste tipuri de cremă nu pot apărea pe primele două straturi. Două torturi cu straturi din aceleași tipuri de cremă sunt diferite dacă acestea sunt dispuse în altă ordine. Primele patru soluții generate sunt, în această ordine:

    1. (castane, mousse, frișcă)
    2. (castane, mousse, ganache)
    3. (castane, șerbet, frișcă)
    4. (castane, șerbet, ganache)

    Indicați a șasea soluție generată.

    • a)(mousse, castane, ganache)
    • b)(mousse, șerbet, frișcă)
    • c)(șerbet, castane, frișcă)
    • d)(șerbet, mousse, ganache)
    Arată răspunsul și explicația

    Răspuns corect: a) (mousse, castane, ganache)

    Pe primele două straturi pot fi doar castane, mousse sau șerbet, iar ultimul strat este frișcă sau ganache; tipurile se încearcă în ordinea din mulțime.

    Primele patru torturi încep cu castane. După (castane, șerbet, ganache) nu mai există alt al doilea strat pentru castane, deci primul strat devine mousse, iar al doilea, cel mai mic posibil, castane: al cincilea tort este (mousse, castane, frișcă), iar al șaselea (mousse, castane, ganache).

  4. Exercițiul 44p

    Un graf orientat cu 8 vârfuri, numerotate de la 1 la 8, are arcele:

    1. (1,2)
    2. (1,3)
    3. (2,3)
    4. (2,6)
    5. (3,2)
    6. (3,4)
    7. (3,6)
    8. (4,5)
    9. (4,7)
    10. (6,1)
    11. (7,4)

    Indicați numărul total de vârfuri ale componentei tare conexe din care face parte vârful 3.

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

    Răspuns corect: c) 4

    Vârfurile 1, 2, 3 și 6 sunt în aceeași componentă tare conexă: 1→3→2→6→1 este un circuit care le cuprinde pe toate.

    Din 3 se ajunge și în 4, 5 și 7, dar din acestea nu se mai poate reveni în 3: 4 și 7 formează o componentă separată, iar din 5 nu pleacă niciun arc. Componenta lui 3 are 4 vârfuri.

  5. Exercițiul 54p

    Un graf neorientat admite un ciclu eulerian, de lungime 11, precum și un ciclu hamiltonian, de lungime 7.

    Indicați numărul de muchii care pot fi eliminate din graf, astfel încât graful parțial obținut să fie arbore.

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

    Răspuns corect: d) 5

    Ciclul eulerian trece o singură dată prin fiecare muchie, deci graful are 11 muchii. Ciclul hamiltonian trece o singură dată prin fiecare nod, deci graful are 7 noduri.

    Un arbore cu 7 noduri are 6 muchii, iar un ciclu hamiltonian arată că graful e conex, deci se poate păstra un astfel de arbore. Se elimină 11 − 6 = 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.

    Scrieți valoarea afișată dacă se citesc, în această ordine, numerele 4, 3, 11 și 25.

     citește m,n,p,q
        (numere naturale nenule, p≤q)
     s←0
    ┌pentru x←p,q execută
    │┌dacă x%m=0 sau x%n=0 atunci
    ││ s←s+x
    │└■
    │┌dacă x%m=0 și x%n=0 atunci
    ││ s←s-x
    │└■
    └■
     scrie s
    Arată răspunsul și explicația

    Răspunsul din barem: 90

    90
    
    Numerele care se împart la m sau la n se adună, iar cele care se împart la amândouă se scad imediat înapoi: se adună, de fapt, numerele dintre p și q care se împart la exact unul dintre m și n.
    Pentru m=4, n=3, între 11 și 25: multiplii lui 3 sunt 12, 15, 18, 21, 24, ai lui 4 sunt 12, 16, 20, 24, iar 12 și 24 se împart la amândouă. Rămân 15 + 18 + 21 + 16 + 20 = 90.
  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.

    Dacă pentru m, n și p se citesc numerele 10, 15, respectiv 2, scrieți două numere care pot fi citite pentru q astfel încât, în urma executării algoritmului, pentru fiecare dintre acestea, valoarea afișată să fie 250.

     citește m,n,p,q
        (numere naturale nenule, p≤q)
     s←0
    ┌pentru x←p,q execută
    │┌dacă x%m=0 sau x%n=0 atunci
    ││ s←s+x
    │└■
    │┌dacă x%m=0 și x%n=0 atunci
    ││ s←s-x
    │└■
    └■
     scrie s
    Arată răspunsul și explicația
    Exemplu: 70 74
    
    Pentru m=10, n=15 și p=2 se adună numerele care se împart la exact unul dintre 10 și 15, de la 2 la q. Numerele adunate sunt 10, 15, 20, 40, 45, 50, 70, 75, … (30 și 60 se împart la amândouă și nu se adună), iar sumele parțiale sunt 10, 25, 45, 85, 130, 180 și 250 după 70. Următorul număr adunat este 75, deci suma este 250 pentru orice q de la 70 la 74.
  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.

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

     citește m,n,p,q
        (numere naturale nenule, p≤q)
     s←0
    ┌pentru x←p,q execută
    │┌dacă x%m=0 sau x%n=0 atunci
    ││ s←s+x
    │└■
    │┌dacă x%m=0 și x%n=0 atunci
    ││ s←s-x
    │└■
    └■
     scrie s
    Arată răspunsul și explicația
    #include <iostream>
    using namespace std;
    
    int main()
    {
        int m, n, p, q, s = 0, x;
        cin >> m >> n >> p >> q;
        for (x = p; x <= q; x++)
        {
            if (x % m == 0 || x % n == 0) s = s + x;
            if (x % m == 0 && x % n == 0) s = s - x;
        }
        cout << s;
        return 0;
    }
    
    pentru x←p,q execută devine for (x = p; x <= q; x++), sau devine ||, iar și devine &&.
  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.

    Scrieți în pseudocod un algoritm, echivalent cu cel dat, înlocuind structura pentru...execută cu o structură repetitivă cu test inițial.

     citește m,n,p,q
        (numere naturale nenule, p≤q)
     s←0
    ┌pentru x←p,q execută
    │┌dacă x%m=0 sau x%n=0 atunci
    ││ s←s+x
    │└■
    │┌dacă x%m=0 și x%n=0 atunci
    ││ s←s-x
    │└■
    └■
     scrie s
    Arată răspunsul și explicația
    citește m,n,p,q (numere naturale nenule, p≤q)
    s←0
    x←p
    ┌cât timp x≤q execută
    │┌dacă x%m=0 sau x%n=0 atunci
    ││ s←s+x
    │└■
    │┌dacă x%m=0 și x%n=0 atunci
    ││ s←s-x
    │└■
    │ x←x+1
    └■
    scrie s
    
    Cu cât timp, contorul se gestionează explicit: x primește valoarea inițială p înainte de buclă, se continuă cât timp x≤q, iar x←x+1 se face la sfârșitul corpului.
  5. Exercițiul 26p

    Variabila c, declarată alăturat, permite accesul la datele fiecăreia dintre cele trei echipe participante la ultima etapă a unui concurs: numele și rezultatul (număr natural din intervalul [0,100]); cele trei echipe au rezultate distincte.

    Scrieți o secvență de instrucțiuni în urma executării căreia să se afișeze pe ecran, separate prin câte un spațiu, numele celor trei echipe, în ordinea descrescătoare a rezultatelor obținute.

    struct echipa
    {  char nume[50];
       int rezultat;
    };
    struct echipa c[3];
    Arată răspunsul și explicația
    int i, j, ord[3] = {0, 1, 2}, aux;
    for (i = 0; i < 2; i++)
        for (j = i + 1; j < 3; j++)
            if (c[ord[i]].rezultat < c[ord[j]].rezultat)
            {
                aux = ord[i];
                ord[i] = ord[j];
                ord[j] = aux;
            }
    cout << c[ord[0]].nume << ' ' << c[ord[1]].nume << ' ' << c[ord[2]].nume;
    
    Tabloul ord ține pozițiile echipelor și se ordonează după rezultate, descrescător, fără să se mute înregistrările propriu-zise. La final se afișează numele echipelor în această ordine. Se poate la fel de bine interschimba direct elementele tabloului c.
  6. Exercițiul 36p

    Variabila p este de tip întreg, iar variabilele s1 și s2 permit memorarea câte unui șir de cel mult 30 de caractere.

    Scrieți ce se afișează în urma executării secvenței alăturate.

    strcpy(s1, "plantau fistic");
    p=strchr(s1,' ')-s1;
    strcpy(s2,s1+p+1); strcpy(s1+p-1,s2+2);
    strcpy(s2+1,s1+2);
    cout<<p<<s2; | printf("%d%s",p,s2);
    Arată răspunsul și explicația

    Răspunsul din barem: 7fantastic

    7fantastic
    
    strchr(s1,' ') indică spațiul, aflat pe poziția 7, deci p = 7, iar s2 devine "fistic", tot ce urmează după spațiu.
    strcpy(s1+p-1, s2+2) scrie de la poziția 6 a lui s1 șirul "stic": s1 devine "plantastic". strcpy(s2+1, s1+2) scrie de la poziția 1 a lui s2 șirul "antastic": s2 devine "fantastic". Se afișează 7 urmat imediat de fantastic.

Subiectul al III-lea30 de puncte

  1. Exercițiul 110p

    Subprogramul DoiTrei are un parametru, n, prin care primește un număr natural (n∈[0,109]). Subprogramul returnează valoarea 1 dacă toate cifrele lui n sunt din mulțimea {2,3} sau valoarea 0 în caz contrar.

    Scrieți definiția completă a subprogramului.

    Exemplu: dacă n=22323 sau n=3, atunci subprogramul returnează 1, iar dacă n=2023 atunci subprogramul returnează 0.

    Arată răspunsul și explicația
    int DoiTrei(int n)
    {
        do
        {
            if (n % 10 != 2 && n % 10 != 3) return 0;
            n = n / 10;
        } while (n != 0);
        return 1;
    }
    
    Cifrele se iau pe rând, de la dreapta. La prima cifră diferită de 2 și de 3 se returnează 0; dacă toate trec verificarea, se returnează 1. Structura do…while verifică și cifra lui n=0, care nu este din mulțime.
  2. Exercițiul 210p

    Suprafața unui loc de joacă pentru copii este împărțită în n∙n zone de formă pătrată dispuse pe n rânduri și n coloane, numerotate de la 1 la n, în fiecare zonă fiind plasat un tobogan, un leagăn, un balansoar sau un carusel. Zonelor li se atribuie câte un cod, în funcție de destinație: codul 0 pentru tobogan, codul 1 pentru leagăn, codul 2 pentru balansoar și codul 3 pentru carusel.

    Scrieți un program C/C++ care citește de la tastatură un număr natural, n (n∈[1,102]), și cele n∙n elemente ale unui tablou bidimensional, reprezentând codurile corespunzătoare zonelor din locul de joacă, în ordinea parcurgerii lor rând după rând, și a fiecărui rând de la stânga la dreapta.

    Programul determină zonele destinate plasării câte unui carusel, care NU au nicio latură comună cu o zonă cu tobogan și, pentru fiecare dintre acestea, afișează pe ecran numărul de ordine al rândului pe care se află. Numerele afișate sunt separate prin câte un spațiu, iar dacă nu există nicio astfel de zonă, se afișează pe ecran mesajul nu exista.

    Exemplu: pentru n=6 și tabloul alăturat se afișează pe ecran, nu neapărat în această ordine, numerele: 2 3 3 6.

    Figura din enunț
    Arată răspunsul și explicația
    #include <iostream>
    using namespace std;
    
    int main()
    {
        int n, a[102][102], i, j, gasit = 0;
        cin >> n;
        for (i = 0; i <= n + 1; i++)
            for (j = 0; j <= n + 1; j++)
                a[i][j] = 1;
        for (i = 1; i <= n; i++)
            for (j = 1; j <= n; j++)
                cin >> a[i][j];
        for (i = 1; i <= n; i++)
            for (j = 1; j <= n; j++)
                if (a[i][j] == 3 && a[i - 1][j] != 0 && a[i + 1][j] != 0 && a[i][j - 1] != 0 && a[i][j + 1] != 0)
                {
                    cout << i << ' ';
                    gasit = 1;
                }
        if (gasit == 0) cout << "nu exista";
        return 0;
    }
    
    Tabloul are o bordură de zone fictive, cu codul 1 (nu tobogan), în jurul suprafeței: așa, și zonele de pe margini sau din colțuri au patru vecini de verificat, fără cazuri separate. Un carusel se afișează dacă niciunul dintre cei patru vecini nu este tobogan. Rândurile se parcurg de sus în jos, deci numerele ies în ordine crescătoare, iar enunțul acceptă orice ordine.
  3. Exercițiul 3.a2p

    O pereche de numere naturale (x,y) se numește p-ordonată dacă x și y au paritate diferită, cu x>y, sau dacă x și y au aceeași paritate.

    Exemplu: (7,4), (8,7), (7,9) sunt perechi p-ordonate, dar (7,8), (8,9) nu sunt perechi p-ordonate. Un șir, format din 2∙n numere naturale, se numește p-ordonat dacă perechile de forma (x,y) sunt p-ordonate, pentru orice x, dintre primii n termeni ai șirului, și orice y, dintre ultimii n termeni ai șirului.

    Fișierul bac.txt conține numere naturale din intervalul [0,106]: pe prima linie un număr nenul, n, iar pe a doua linie un șir de 2∙n numere, separate prin câte un spațiu. Se cere să se afișeze pe ecran mesajul DA, în cazul în care șirul aflat în fișier este p-ordonat, sau mesajul NU, în caz contrar. Proiectați un algoritm eficient din punctul de vedere al timpului de executare și al memoriei utilizate.

    Exemplu: dacă fișierul are unul dintre conținuturile de mai jos, se afișează pe ecran mesajul DA.

    5
    22 37 21 8 15 2 3 14 4 5
    
    sau
    
    5
    22 36 20 8 14 44 42 4 2 5

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

    Arată răspunsul și explicația
    O pereche (x, y) nu este p-ordonată doar dacă x și y au parități diferite și x < y. Șirul este p-ordonat exact când nu există o astfel de pereche între un x din prima jumătate și un y din a doua.
    
    Pentru un x par, cel mai „periculos” y este cel mai mare impar din a doua jumătate; pentru un x impar, cel mai mare par. Deci șirul este p-ordonat exact când cel mai mic par din prima jumătate este mai mare decât cel mai mare impar din a doua și cel mai mic impar din prima jumătate este mai mare decât cel mai mare par din a doua.
    
    Se citesc primii n termeni, reținând minimul par și minimul impar (pornite de la 1000001), apoi ultimii n termeni, reținând maximul par și maximul impar (pornite de la -1). La final se fac cele două comparații și se afișează DA sau NU.
    
    Eficiență: fiecare număr se prelucrează o singură dată, în timp constant, fără să fie memorat, deci timpul este liniar, iar memoria constantă.
  4. Exercițiul 3.b8p

    O pereche de numere naturale (x,y) se numește p-ordonată dacă x și y au paritate diferită, cu x>y, sau dacă x și y au aceeași paritate.

    Exemplu: (7,4), (8,7), (7,9) sunt perechi p-ordonate, dar (7,8), (8,9) nu sunt perechi p-ordonate. Un șir, format din 2∙n numere naturale, se numește p-ordonat dacă perechile de forma (x,y) sunt p-ordonate, pentru orice x, dintre primii n termeni ai șirului, și orice y, dintre ultimii n termeni ai șirului.

    Fișierul bac.txt conține numere naturale din intervalul [0,106]: pe prima linie un număr nenul, n, iar pe a doua linie un șir de 2∙n numere, separate prin câte un spațiu. Se cere să se afișeze pe ecran mesajul DA, în cazul în care șirul aflat în fișier este p-ordonat, sau mesajul NU, în caz contrar. Proiectați un algoritm eficient din punctul de vedere al timpului de executare și al memoriei utilizate.

    Exemplu: dacă fișierul are unul dintre conținuturile de mai jos, se afișează pe ecran mesajul DA.

    5
    22 37 21 8 15 2 3 14 4 5
    
    sau
    
    5
    22 36 20 8 14 44 42 4 2 5

    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 n, i, x, p1 = 1000001, i1 = 1000001, p2 = -1, i2 = -1;
        fin >> n;
        for (i = 0; i < n; i++)
        {
            fin >> x;
            if (x % 2 == 0)
            {
                if (x < p1) p1 = x;
            }
            else if (x < i1) i1 = x;
        }
        for (i = 0; i < n; i++)
        {
            fin >> x;
            if (x % 2 == 0)
            {
                if (x > p2) p2 = x;
            }
            else if (x > i2) i2 = x;
        }
        fin.close();
        if (p1 > i2 && i1 > p2) cout << "DA";
        else cout << "NU";
        return 0;
    }
    
    Programul face pașii de la 3.a. Dacă o jumătate nu are numere pare (sau impare), minimul rămâne 1000001 și maximul -1, iar comparațiile corespunzătoare sunt adevărate de la sine, cum trebuie: nu există perechi de acel tip.

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