Subiect și barem BAC 2023 Informatică C/C++ (mate-info)
2023
August–Septembrie
Varianta 7
Rezolvare explicată

Rezolvare BAC 2023 Informatică C/C++ (mate-info) — August–Septembrie, varianta 7, pas cu pas

Subiectul și baremul sunt documentele oficiale ale Ministerului Educației; rezolvarea de mai jos este explicația echipei MeditatiiDirect.ro, cu punctajul din barem pentru fiecare cerință.

Rezolvarea completă a subiectului de Bacalaureat 2023 la Informatică, limbajul C/C++, profil mate-info, sesiunea august–septembrie, varianta 7. Pentru fiecare item ai răspunsul, raționamentul pas cu pas, codul C++ complet și punctajul din baremul oficial.

Sfat: încearcă întâi singur fiecare cerință, apoi verifică aici. La programe, baremul punctează orice soluție corectă — nu trebuie să scrii exact codul de mai jos.

Subiectul I (20 de puncte)

Răspunsuri: 1 – b, 2 – c, 3 – a, 4 – b, 5 – d (câte 4 puncte).

1. Valorile pentru care y%x-(x/y)*3!=0 este 1 → b. x=25 și y=15

Pentru b: 15%25 = 15, 25/15 = 1, deci 15−1⋅3=12≠015 - 1 \cdot 3 = 12 \ne 0 → valoarea 1 ✔.

  • a. 75%25 = 0, 25/75 = 0 → 0−0=00 - 0 = 0 → expresia e 0.
  • c. y = 0 → x/y este împărțire la zero (eroare).
  • d. 30%10 = 0, 10/30 = 0 → 0.

2. Valoarea f(3,2) → c. 9

Funcția calculează xyx^y prin ridicare rapidă la putere: xy=(xy/2)2x^y = (x^{y/2})^2, înmulțit încă o dată cu x dacă y e impar.

  • f(3,0) = 1; f(3,1) = 1·1·3 = 3 (1 impar); f(3,2) = 3·3 = 9 (2 par).

3. Șirul s → a. 20123

strcpy(s+3,"23") scrie „23” începând cu poziția 3 (a patra literă), peste „9” și peste terminatorul de șir: „201” + „23” = „20123”.

4. Penultima soluție → b. (cireș, lămâie, salcâm)

Soluțiile sunt combinări de 3 din 5, în ordine lexicografică. Ultimele combinări sunt …, (cireș, iris, salcâm), (cireș, lămâie, salcâm), (iris, lămâie, salcâm) — ultima.

  • a. este antepenultima. c. nu respectă ordinea din mulțime (lămâie înainte de iris). d. este ultima.

5. Valori posibile pentru x și y → d. 3 și 3

Verificăm fiecare variantă:

  • a. Nodul 5 cu gradul 4 ar fi legat de toate celelalte noduri, inclusiv de nodul 2, care ar avea gradul 0 — contradicție.
  • b. Gradul 5 este imposibil într-un graf cu 5 noduri (maximum 4).
  • c. Suma gradelor 2+2+3+3+3=132 + 2 + 3 + 3 + 3 = 13 este impară — imposibil.
  • d. Gradele 2, 3, 3, 3, 3 (suma 14 → 7 muchii) se pot realiza, de exemplu: [1,2], [1,3], [2,4], [2,5], [3,4], [3,5], [4,5] ✔.

Subiectul al II-lea (40 de puncte)

1. Algoritmul în pseudocod

Pentru fiecare pereche (a, b): bucla reduce a la prima lui cifră, iar p devine 10k−110^{k-1} (k = numărul de cifre ale lui a). Apoi a←prima cifra˘⋅p+ba \leftarrow \text{prima cifră} \cdot p + b, adică prima cifră a lui a urmată de b „pe restul pozițiilor”. Dacă rezultatul diferă de valoarea inițială a lui a, x crește. Se afișează numărul de perechi pentru care b nu este exact numărul format din cifrele lui a fără prima.

a) Pentru 3, 746, 82, 3067, 67, 78, 178 → 2

abPrima cifră · pRezultat≠ a?
746827 · 100782da → x = 1
3067673 · 10003067nu
781787 · 10248da → x = 2

Se afișează 2. (6p)

b) n = 2, valori din [0, 9], se afișează 0

Pentru a de o cifră, p = 1 și rezultatul este a+ba + b, egal cu a doar dacă b = 0. Un șir corect: 5, 0, 7, 0 (orice șir de forma x, 0, y, 0). (6p)

c) Programul C/C++ (10p)

cppcod
#include <iostream>
using namespace std;

int main()
{
    int n, x = 0, a, b, c, p;
    cin >> n;
    while (n > 0)
    {
        cin >> a >> b;
        c = a; p = 1;
        while (a > 9)
        {
            a = a / 10;
            p = p * 10;
        }
        a = a * p + b;
        if (a != c)
            x = x + 1;
        n = n - 1;
    }
    cout << x;
    return 0;
}

d) Algoritm echivalent cu „pentru … execută” (6p)

Bucla exterioară se execută de n ori, iar valoarea lui n nu mai este folosită ulterior:

textcod
citește n (număr natural nenul)
x ← 0
┌pentru i ← 1, n execută
│  citește a, b (numere naturale)
│  c ← a; p ← 1
│ ┌cât timp a > 9 execută
│ │  a ← [a/10]; p ← p*10
│ └■
│  a ← a*p + b
│ ┌dacă a ≠ c atunci x ← x + 1
│ └■
└■
scrie x

2. Rădăcini cu număr minim de niveluri (6p)

Numărul de niveluri este minim când rădăcina se află în centrul arborelui. Cel mai lung lanț este, de exemplu, 1 – 2 – 3 – 4 (lungime 3), iar mijlocul lui este format din nodurile 2 și 3. Cu rădăcina 2 sau 3 arborele are 3 niveluri (0, 1, 2); cu orice altă rădăcină are cel puțin 4.

3. Prima literă sau * (6p)

cppcod
if (p.pret < 100)
    a = p.denumire[0];
else
    a = '*';

Prima literă a denumirii este caracterul de pe poziția 0 al șirului; constanta caracter se scrie între apostrofuri.

Subiectul al III-lea (30 de puncte)

1. Subprogramul DNPI (10p)

Parcurgem divizorii lui n în perechi (d, n/d) cu d2≤nd^2 \le n — maximum ~31 623 de pași pentru n≤109n \le 10^9. Pentru fiecare divizor impar verificăm dacă nu este prim (1 nu este prim, deci se afișează).

cppcod
int prim(int x)
{
    if (x < 2) return 0;
    for (int d = 2; d * d <= x; d++)
        if (x % d == 0) return 0;
    return 1;
}

void DNPI(int n)
{
    for (int d = 1; d * d <= n; d++)
        if (n % d == 0)
        {
            int e = n / d;
            if (d % 2 == 1 && !prim(d)) cout << d << ' ';
            if (e != d && e % 2 == 1 && !prim(e)) cout << e << ' ';
        }
}

Verificare: n = 90 → divizori impari 1, 3, 5, 9, 15, 45; eliminăm primii 3 și 5 → se afișează 1, 9, 15, 45 (ordinea nu contează) ✔.

2. Pătratul de valoare maximă (10p)

Fiecare pătrat 2×2 are colțul stânga-sus pe poziția (i, j), cu i<m−1i < m-1 și j<n−1j < n-1. Calculăm suma celor patru celule și reținem maximul.

cppcod
#include <iostream>
using namespace std;

int main()
{
    int m, n, a[21][21], i, j, maxim = -1;
    cin >> m >> n;
    for (i = 0; i < m; i++)
        for (j = 0; j < n; j++)
            cin >> a[i][j];
    for (i = 0; i + 1 < m; i++)
        for (j = 0; j + 1 < n; j++)
        {
            int s = a[i][j] + a[i][j + 1] + a[i + 1][j] + a[i + 1][j + 1];
            if (s > maxim) maxim = s;
        }
    cout << maxim;
    return 0;
}

Verificare pe exemplu: pătratul cu celulele 10, 1, 13, 12 (liniile 2–3, coloanele 2–3) are suma 36, cea mai mare ✔.

3. Numărul maxim de perechi cu valori egale

a) Descrierea algoritmului (2p)

Valorile sunt între 0 și 99, deci folosim doi vectori de frecvență: fa[v] = de câte ori apare v în A și fb[v] = de câte ori apare v în B, completați la citire. Pentru o valoare v putem forma cel mult min⁡(fa[v],fb[v])\min(fa[v], fb[v]) perechi (fiecare poziție se folosește o singură dată), iar acest număr se poate atinge. Răspunsul este ∑v=099min⁡(fa[v],fb[v])\sum_{v=0}^{99} \min(fa[v], fb[v]).

Eficiență: citirea este liniară în m+nm + n, iar însumarea are 100 de pași. Nu memorăm șirurile și nu comparăm toate perechile de poziții (ar fi O(m⋅n)O(m \cdot n)).

b) Programul C/C++ (8p)

cppcod
#include <fstream>
#include <iostream>
using namespace std;

int fa[100], fb[100];

int main()
{
    ifstream f("date.in");
    int m, n, x, i;
    long long total = 0;
    f >> m >> n;
    for (i = 0; i < m; i++) { f >> x; fa[x]++; }
    for (i = 0; i < n; i++) { f >> x; fb[x]++; }
    for (x = 0; x < 100; x++)
        total += (fa[x] < fb[x]) ? fa[x] : fb[x];
    cout << total;
    f.close();
    return 0;
}

Verificare pe exemplu: valoarea 1: min(2, 3) = 2; 3: min(1, 2) = 1; 5: min(3, 2) = 2; 0: min(1, 1) = 1; 4 și 7 nu apar în ambele. Total 6 ✔.

Ce merită reținut din varianta 7

  • Împărțirea la zero face o expresie invalidă — elimină imediat varianta.
  • Ridicarea rapidă la putere: xy=(xy/2)2⋅xy mod 2x^y = (x^{y/2})^2 \cdot x^{y \bmod 2}.
  • strcpy(s+k, …) suprascrie șirul începând cu poziția k.
  • Șiruri de grade: suma trebuie să fie pară și niciun grad nu poate depăși n − 1.
  • Perechi cu valori egale: suma minimelor frecvențelor.

Vrei să iei nota pe care ți-o dorești la BAC 2023?

Ai lucrat subiectul de Informatică C/C++ (mate-info)? Pe MeditatiiDirect.ro îl poți relua cu un profesor sau cu Profesorul AI, exact pe punctele unde ai pierdut puncte la barem.

Alte subiecte BAC Informatică C/C++ (mate-info) rezolvate