Subiect și barem BAC 2024 Informatică C/C++ (mate-info)
2024
Sesiune specială
Varianta 4
Rezolvare explicată

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

1. Echivalentă cu !(x>25 || y<6) → a. x<=25 && y>=6

După De Morgan, ¬(A∨B)=¬A∧¬B\neg(A \lor B) = \neg A \land \neg B: !(x>25) devine x<=25, !(y<6) devine y>=6, iar || devine &&.

  • b. și d. păstrează || — greșit.
  • c. nu neagă și a doua condiție.

2. Ce afișează f(9) → b. 545522

  • f(9): 9 nu e multiplu de 5 → x = 9·5/2 = 22, apel f(22); la revenire afișează 22.
  • f(22): x = 22·5/2 = 55, apel f(55); la revenire afișează 55.
  • f(55): 55 e multiplu de 5 → x = 54, afișează 54.

Ordinea afișării (de la cel mai adânc apel): 54, 55, 22 → 545522.

3. Soluțiile din jurul lui SV-68-CAB → d. SV-68-BAC, TL-24-BAC

Grupul de litere are doar două variante: BAC, apoi CAB. Deci înaintea lui SV-68-CAB este SV-68-BAC. După el, 68 este ultimul număr posibil (cifre strict crescătoare din {2,4,6,8}), iar SV-68-CAB este ultima soluție cu SV; urmează primul indicativ următor, TL, cu primul număr și primul grup: TL-24-BAC.

  • a. „86” nu are cifrele în ordine crescătoare; b., c. nu sunt vecine cu SV-68-CAB.

4. Anul achiziționării → d. t.achizitionare.an

Variabila este t, câmpul de tip data se numește achizitionare, iar acesta are câmpul an. Variantele a și c folosesc numele tipului (telefon), iar b folosește numele tipului data în locul câmpului.

5. Lungimea maximă a unui drum elementar → c. 4

Un drum elementar nu repetă vârfuri, deci trece prin cel mult 5 vârfuri și are cel mult 4 arce. Lungimea 4 se poate atinge: de exemplu, graful cu arcele (i, j) pentru toate perechile i < j are gradele interne + externe egale cu 4 pentru fiecare vârf și conține drumul 1→2→3→4→5. Variantele 10, 8 depășesc numărul de vârfuri.

Subiectul al II-lea (40 de puncte)

1. Algoritmul în pseudocod

Pentru fiecare i de la 1 la n, m devine i fără factorii 2 (cea mai mare parte impară a lui i). Se afișează m doar dacă m ≠ i, adică doar pentru i par.

a) Pentru n = 10 → 1 1 3 1 5

i = 2 → 1; i = 4 → 1; i = 6 → 3; i = 8 → 1; i = 10 → 5. Numerele impare nu se afișează (m = i). (6p)

b) Exact patru valori egale cu 1

Se afișează 1 pentru fiecare putere a lui 2 cel puțin 2: 2, 4, 8, 16, 32, … Ca să fie exact 4 (2, 4, 8, 16), trebuie 16≤n≤3116 \le n \le 31, de exemplu 16 și 31. (6p)

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

cppcod
#include <iostream>
using namespace std;

int main()
{
    int n, i = 1, m;
    cin >> n;
    while (i <= n)
    {
        m = i;
        while (m % 2 == 0)
            m = m / 2;
        if (m != i)
            cout << m << ' ';
        i = i + 1;
    }
    return 0;
}

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

textcod
citește n (număr natural, n ≥ 2)
┌pentru i ← 1, n execută
│  m ← i
│ ┌cât timp m%2 = 0 execută
│ │  m ← [m/2]
│ └■
│ ┌dacă m ≠ i atunci scrie m, ' '
│ └■
└■

Inițializarea i ← 1 și actualizarea i ← i + 1 sunt preluate de structura „pentru”.

2. Graf parțial conex și fără cicluri (6p)

Un graf parțial păstrează toate nodurile, eliminând doar muchii. Conex și fără cicluri înseamnă arbore: cu 6 noduri, păstrăm 5 muchii. Graful are 7 muchii și două cicluri: 2–4–5–2 și 4–5–6–4. Eliminăm [4,5] și [5,6] și păstrăm [1,2], [2,3], [2,4], [2,5], [4,6]:

textcod
1: 2
2: 1, 3, 4, 5
3: 2
4: 2, 6
5: 2
6: 4

3. Cuvânt de două litere cu o vocală și o consoană (6p)

Cuvântul trebuie să aibă exact 2 litere, iar una să fie vocală și cealaltă nu: „este vocală” pentru prima literă trebuie să fie diferit de „este vocală” pentru a doua.

cppcod
c = 0;
for (i = 1; i <= 10; i++)
{
    cin >> s;
    if (strlen(s) == 2 &&
        (strchr("aeiou", s[0]) != NULL) != (strchr("aeiou", s[1]) != NULL))
        c = 1;
}

Exemplu: „au” are două vocale, „el” are vocală + consoană → c = 1 ✔.

Subiectul al III-lea (30 de puncte)

1. Subprogramul fulg (10p)

n reprezintă o aglomerare studiată dacă are exact 9 cifre, toate din {1, 2, 3, 4}, și fiecare dintre cele patru cifre apare cel puțin o dată. Parcurgem cifrele, le numărăm și marcăm ce tipuri au apărut.

cppcod
int fulg(int n)
{
    int nr = 0, ap[10] = {0};
    while (n != 0)
    {
        int c = n % 10;
        if (c < 1 || c > 4) return 0;
        ap[c] = 1;
        nr++;
        n = n / 10;
    }
    if (nr == 9 && ap[1] && ap[2] && ap[3] && ap[4]) return 1;
    return 0;
}

Verificare: 112243413 → 9 cifre din {1,…,4}, toate tipurile prezente → 1 ✔; 12314 (5 cifre) → 0; 112253513 (cifra 5) → 0; 112243457 → 0; 111122223 (lipsește 4) → 0 ✔.

2. Tabloul cu valori generate (10p)

Lipirea lui b la dreapta lui a este a⋅10k+ba \cdot 10^{k} + b, unde k este numărul de cifre ale lui b. Calculăm ambele variante (i lipit cu j și j lipit cu i) și o păstrăm pe cea mai mică.

cppcod
#include <iostream>
using namespace std;

int lipire(int a, int b)
{
    int p = 1;
    while (p <= b) p = p * 10;   // 10^(numărul de cifre ale lui b)
    return a * p + b;
}

int main()
{
    int m, n, a[51][51], i, j;
    cin >> m >> n;
    for (i = 1; i <= m; i++)
        for (j = 1; j <= n; j++)
        {
            int x = lipire(i, j), y = lipire(j, i);
            a[i][j] = (x < y) ? x : y;
        }
    for (i = 1; i <= m; i++)
    {
        for (j = 1; j <= n; j++)
            cout << a[i][j] << ' ';
        cout << '\n';
    }
    return 0;
}

Verificare: pentru i = 5, j = 2: 52 și 25 → 25 ✔; pentru i = j = 3: 33 ✔. Se obține exact tabloul din exemplu.

3. Primul și ultimul număr cu cifra maximă

a) Descrierea algoritmului (2p)

Citim numerele pe rând și calculăm cifra maximă a fiecăruia. Reținem cifra maximă globală cmax, primul număr care o conține (p), ultimul (u) și câte numere o conțin (nr). Dacă numărul curent are o cifră mai mare decât cmax, reluăm totul de la el (p = u = x, nr = 1); dacă are cifra maximă egală cu cmax, actualizăm u = x și creștem nr. La final, dacă nr < 2, afișăm „nu exista”, altfel p și u.

Eficiență: o singură parcurgere → timp liniar; doar câteva variabile simple → memorie O(1).

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

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

int main()
{
    ifstream f("numere.in");
    int x, cmax = -1, p = 0, u = 0, nr = 0;
    while (f >> x)
    {
        int c = (x % 10 > x / 10) ? x % 10 : x / 10;   // cifra maximă a lui x (x < 100)
        if (c > cmax)
        {
            cmax = c; p = x; u = x; nr = 1;
        }
        else if (c == cmax)
        {
            u = x; nr++;
        }
    }
    if (nr < 2) cout << "nu exista";
    else cout << p << ' ' << u;
    f.close();
    return 0;
}

Verificare pe exemple: cifra maximă 8 apare în 38, 87, 8, 82 → 38 82 ✔; în al doilea exemplu ultimul este 38 → 38 38 ✔; în al treilea doar 38 conține 8 → nu exista ✔.

Ce merită reținut din varianta 4

  • De Morgan: negația unei disjuncții este conjuncția negațiilor.
  • Recursivitate: afișările de după apel apar în ordine inversă apelurilor.
  • Drum elementar: cu n vârfuri, lungimea maximă este n − 1.
  • Arbore parțial: din n noduri păstrezi n − 1 muchii, eliminând câte o muchie din fiecare ciclu.
  • Alipirea numerelor: a⋅10nr. cifre(b)+ba \cdot 10^{\text{nr. cifre}(b)} + b.

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

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