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

Rezolvare BAC 2022 Informatică C/C++ (mate-info) — August–Septembrie, varianta 5, 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 2022 la Informatică, limbajul C/C++, profil mate-info, sesiunea august–septembrie, varianta 5. 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 – a, 3 – d, 4 – c, 5 – b (câte 4 puncte).

1. Expresie echivalentă cu x>=3 && x<10 → b. !(x<3 || x>=10)

Conform legilor lui De Morgan, !(x<3 || x>=10) = !(x<3) && !(x>=10) = x>=3 && x<10.

  • a. !(x<3 && x>=10) — condiția din paranteză e mereu falsă, deci expresia e mereu 1. Greșit.
  • c. x<3 && ... — adevărată pentru x < 3. Greșit.
  • d. folosește || și x>=10, adevărată de exemplu pentru x = 20. Greșit.

2. Completarea apelului recursiv → a. y+2

Funcția testează primalitatea lui x încercând divizorii impari 3, 5, 7, … până când y*y > x. Numerele pare (în afară de 2) sunt eliminate de la început, deci e suficient să trecem la următorul număr impar: f(x, y+2).

  • y-2 și y/2 scad divizorul (ajung la 1 sau 0 → rezultat greșit/împărțire la 0), iar y*2 sare peste divizori (3, 6, 12…: ratează 5, 7).

3. Soluția de după (gutuie, prună, caisă) → d. (prună, caisă, piersică)

Ordinea: măr, gutuie, prună, caisă, piersică; combinări de câte 3, fără gutuie + piersică împreună. După (gutuie, prună, caisă) ar urma (gutuie, prună, piersică) și (gutuie, caisă, piersică) — ambele interzise. Se trece la seturile care încep cu prună: (prună, caisă, piersică).

4. A[20][j] pe diagonala secundară → c. 79

Pe diagonala secundară a unui tablou n×n (indici de la 0): i + j = n − 1. Aici 20 + j = 99, deci j = 79.

5. Celelalte două muchii → b. [1,4] și [5,7]

Lanțul 1, 2, 7, 5, 4, 6 are nevoie de muchiile [1,2], [2,7], [7,5], [5,4], [4,6]. Dintre ele lipsește din cele date doar [5,7], deci aceasta e obligatorie → rămân variantele b și d.

  • d. cu [3,6] am avea lanțul 1, 2, 7, 5, 4, 6, 3 de lungime 6 — mai lung, deci cel dat n-ar mai fi maxim. Greșit.
  • b. cu [1,4]: nodul 3 e legat doar de 4, iar lanțurile maxime au lungimea 5. ✔

Subiectul al II-lea (40 de puncte)

1. Algoritmul în pseudocod

Bucla interioară este algoritmul lui Euclid prin scăderi: calculează cmmdc(m, y). Bucla exterioară ia pe rând y = n, n−1, n−2, … și se oprește la primul y cu cmmdc(m, y) ≠ 1. Cum n a fost deja decrementat, se afișează n+1, adică chiar acel y: cel mai mare număr ≤ n care nu este prim cu m.

a) Pentru m = 21, n = 47 → 45

ycmmdc(21, y)continuă?
471da
461da
453nu

La oprire n = 44, se afișează n+1 = 45. (6p)

b) m = 5, se afișează 10

Cel mai mare număr ≤ n care are un divizor comun cu 5 (adică multiplu de 5) trebuie să fie 10 → n ∈ [10, 14]. De exemplu 10 și 14 (orice două din 10, 11, 12, 13, 14). (6p)

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

cppcod
#include <iostream>
using namespace std;

int main()
{
    int m, n, x, y;
    cin >> m >> n;
    x = 1;
    while (x == 1)
    {
        x = m; y = n; n = n - 1;
        while (x != y)
            if (x > y) x = x - y;
            else y = y - x;
    }
    cout << n + 1;
    return 0;
}

Barem: variabile 1p, citire 1p, afișare 1p, decizie 2p, repetitive 3p, atribuiri 1p, corectitudine 1p.

d) Algoritm cu structură repetitivă cu test final (6p)

Prima buclă se execută sigur o dată (x = 1 inițial), deci o putem înlocui direct cu repetă … până când x ≠ 1.

textcod
citește m, n (numere naturale nenule, m<n)
┌repetă
│  x ← m; y ← n; n ← n − 1
│ ┌cât timp x ≠ y execută
│ │ ┌dacă x > y atunci x ← x − y
│ │ │altfel y ← y − x
│ │ └■
│ └■
└până când x ≠ 1
scrie n + 1

2. Rădăcini pentru care nodul 5 are doi „frați” → 2 și 8 (6p)

Vecinii lui 5 sunt 2, 4, 6, 8. Pentru ca 5 să aibă doi frați, tatăl lui 5 trebuie să aibă exact 3 fii.

  • Rădăcina 2: fiii lui 2 sunt 3, 5, 7 → frații lui 5 sunt 3 și 7 ✔.
  • Rădăcina 8: fiii lui 8 sunt 1, 5, 9 → frații lui 5 sunt 1 și 9 ✔.

3. Mesaj după temperatură (6p)

cppcod
if (x.temperatura > 11) cout << "CALDUROS";
else if (x.temperatura < 10) cout << "RACOROS";
else cout << "NORMAL";

Câmpul se accesează cu x.temperatura; cazul „NORMAL” acoperă temperaturile 10 și 11.

Subiectul al III-lea (30 de puncte)

1. Subprogramul schimb (10p)

Calculăm 10p10^p, extragem cifra de pe poziția p cu (n / 10^p) % 10, o scădem și adăugăm noua cifră înmulțită cu 10p10^p. Parametrul n este transmis prin referință, pentru că rezultatul se întoarce prin el.

cppcod
void schimb(int &n, int x, int p)
{
    int put = 1;
    for (int i = 1; i <= p; i++) put = put * 10;
    int c = n / put % 10;          // cifra de pe poziția p
    n = n - c * put + x * put;
}

Exemplu: n = 12587, p = 3 → put = 1000, c = 2 → n = 12587 − 2000 + 6000 = 16587 ✔.

2. Codificarea parolei cu vocale prietene (10p)

Vocala prietenă a unei consoane c este cea mai apropiată vocală aflată înaintea ei în alfabet. Pornim de la c și coborâm până dăm de o vocală (întotdeauna există, pentru că „a” e prima literă).

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

int main()
{
    char s[51];
    cin >> s;
    for (int i = 0; s[i]; i++)
        if (strchr("aeiou", s[i]) == NULL)      // consoană
        {
            char v = s[i];
            while (strchr("aeiou", v) == NULL) v--;
            s[i] = v;
        }
    cout << s;
    return 0;
}

Test: „rame” → r→o, m→i → oaie; „sport” → s→o, p→o, r→o, t→o, o rămâne → ooooo ✔.

3. Secvențe paritare de lungime maximă

a) Descrierea algoritmului (2p)

Citim numerele pe rând, păstrând doar termenul anterior x și pe cel curent y. Dacă au aceeași paritate, lungimea secvenței curente L crește, altfel redevine 1. După fiecare pas: dacă L > Lmax, atunci Lmax = L și nr = 1; dacă L == Lmax, nr++.

Eficiență: o singură parcurgere a fișierului → timp liniar; nu memorăm șirul, doar câteva variabile → memorie O(1).

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

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

int main()
{
    ifstream f("bac.txt");
    int x, y, L = 1, Lmax = 0, nr = 0;
    f >> x;
    while (f >> y)
    {
        if (x % 2 == y % 2) L++;
        else L = 1;
        if (L > 1)
        {
            if (L > Lmax) { Lmax = L; nr = 1; }
            else if (L == Lmax) nr++;
        }
        x = y;
    }
    cout << nr << ' ' << Lmax;
    f.close();
    return 0;
}

Verificare pe exemplu: secvențele de lungime maximă 5 sunt 3 5 1 7 9; 11 15 17 21 11; 11 15 17 21 11; 2 6 4 0 16 → se afișează 4 5 ✔.

Ce merită reținut din varianta 5

  • De Morgan: !(A || B) ⇔ !A && !B.
  • Diagonala secundară (indici de la 0): i + j = n − 1.
  • Euclid prin scăderi: cât timp x≠y cu scăderi calculează cmmdc.
  • Vecinii unui nod în arbore: frații depind de alegerea rădăcinii — tatăl trebuie să aibă exact numărul potrivit de fii.
  • Secvențe maxime: compară mereu termenul curent cu cel anterior și numără egalitățile cu maximul.

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

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