Top 10 cele mai frecvente greșeli la BAC Informatică și cum să le eviți
Cele mai des întâlnite greșeli la BAC Informatică în C++: off-by-one, citire date, overflow, depășire timp și altele, fiecare cu soluția clară ca să le eviți.
La BAC Informatică nu pici pentru că nu știi să programezi. Pici pentru greșeli mici, repetate, pe care le faci sub presiunea timpului: un < în loc de <=, un int care trebuia să fie long long, un vector citit greșit. Vestea bună? Aceste greșeli se repetă de la an la an, ceea ce înseamnă că poți învăța să le recunoști din timp. Hai să le luăm pe rând, pe cele mai frecvente 10, și să vedem exact cum scapi de ele.
Greșelile de logică și indexare
Acestea sunt cele care îți strică punctaje întregi fără să-ți dai seama în timpul examenului. Programul compilează, rulează, dar dă răspunsuri ușor greșite.
1. Off-by-one (eroarea de unu)
Cea mai clasică greșeală din toate timpurile. Apare când confunzi limitele unui interval: pornești de la 0 în loc de 1, sau te oprești la n în loc de n-1. Rezultatul? Procesezi un element în plus sau sari peste unul.
// GREȘIT — accesezi v[n], care este în afara vectorului
for (int i = 0; i <= n; i++)
cout << v[i] << " ";
// CORECT — ultimul index valid este n-1
for (int i = 0; i < n; i++)
cout << v[i] << " ";
Ca să eviți: stabilește de la început dacă indexezi de la 0 sau de la 1 și fii consecvent în tot programul. Dacă citești în v[1]...v[n], atunci buclele trebuie să meargă for (int i = 1; i <= n; i++).
2. Indexare în afara vectorului
Strâns legată de off-by-one, dar mai periculoasă: accesezi v[i] cu un i care nu există. În C++ asta nu dă neapărat eroare — citește memorie aiurea și produce rezultate imprevizibile sau crash-uri care îți pică testul.
Regula de aur: dacă ai declarat
int v[100];, indecșii valizi sunt de la0la99. Niciodatăv[100]. Declară mereu vectorul cu câteva poziții peste limita maximă din cerință — dacănpoate fi 1000, declarăv[1005].
3. Neinițializarea variabilelor
În C++, o variabilă locală neinițializată conține gunoi (o valoare aleatoare). Dacă aduni într-o sumă fără să o pui pe 0 mai întâi, rezultatul e total greșit.
// GREȘIT — s pornește de la o valoare necunoscută
int s;
for (int i = 0; i < n; i++)
s += v[i];
// CORECT — inițializezi acumulatorul
int s = 0;
for (int i = 0; i < n; i++)
s += v[i];
Atenție specială la max și min: nu îi inițializa cu 0, pentru că poți avea numere negative. Folosește prima valoare din date sau o constantă suficient de mare (max cu o valoare foarte mică, min cu una foarte mare).
Greșelile legate de date și citire
Aici pierzi puncte chiar înainte să începi algoritmul propriu-zis, fiindcă lucrezi cu date citite greșit.
4. Citirea greșită a datelor
Mulți elevi pierd puncte pentru că nu citesc atent formatul din enunț. Câte numere sunt pe un rând? Există un n la început care îți spune câte valori urmează? Citești dintr-un fișier sau de la tastatură?
// Pattern corect pentru "pe prima linie n, apoi n numere"
int n;
cin >> n;
for (int i = 0; i < n; i++)
cin >> v[i];
Dacă subiectul cere lucrul cu fișiere (bac.in, bac.out), nu uita de ifstream și ofstream. Un program care citește de la tastatură când trebuia să citească din fișier ia zero pe acel subict, oricât de corect ar fi algoritmul.
5. Confuzia între citirea cu cin și getline
Când amesteci cin >> ceva cu getline, rămâne un caracter newline în buffer și getline citește un șir gol. E o capcană tipică la problemele cu propoziții și cuvinte.
int n;
cin >> n;
cin.ignore(); // CRUCIAL — consumă newline-ul rămas
string linie;
getline(cin, linie);
Dacă uiți cin.ignore(), primul getline îți va returna un șir gol și tot restul se va decala.
Greșelile de tipuri și performanță
Acestea sunt cele mai dureroase, pentru că algoritmul tău e corect, dar tot iei punctaj parțial sau zero.
6. Overflow (depășirea tipului de date)
Un int în C++ ține valori până la aproximativ 2 miliarde. Dacă înmulțești două numere mari sau aduni multe valori, depășești limita și rezultatul devine negativ sau aberant.
// GREȘIT — a*b depășește int chiar dacă a și b încap în int
int a = 100000, b = 100000;
int produs = a * b; // overflow!
// CORECT — folosește long long
long long produs = 1LL * a * b;
Iată un ghid rapid al limitelor:
| Tip | Limită aproximativă | Când îl folosești |
|---|---|---|
int | ~2 × 10⁹ | numărători, indecși, valori mici |
long long | ~9 × 10¹⁸ | sume mari, produse, factorial |
double | foarte mare, dar imprecis | calcule cu zecimale |
Regula practică: dacă în enunț apar numere mari sau cuvinte ca "sumă", "produs", "factorial", gândește-te imediat la long long. Nu costă nimic în plus și te scapă de overflow.
7. Depășirea timpului de execuție (Time Limit Exceeded)
Programul tău e corect, dar prea lent pentru datele mari. De obicei vinovat e un algoritm cu prea multe bucle imbricate. Dacă n poate fi 100.000 și tu ai două bucle una în alta, faci 10 miliarde de operații — mult peste limita de timp.
Verifică mereu constrângerile din enunț. Dacă
n ≤ 1.000.000, ai nevoie de un algoritm liniar sau aproape liniar. Dacăn ≤ 1.000, îți permiți două bucle imbricate. Mărimea luinîți spune ce complexitate ai voie să folosești.
Un truc simplu care accelerează citirea/scrierea masivă în C++:
ios_base::sync_with_stdio(false);
cin.tie(NULL);
8. Împărțirea întreagă neintenționată
În C++, 7 / 2 este 3, nu 3.5, pentru că ambii operanzi sunt întregi. E o sursă constantă de erori la calculul mediilor și procentelor.
// GREȘIT — rezultatul e trunchiat la întreg
double media = (a + b) / 2;
// CORECT — forțează calculul în virgulă mobilă
double media = (a + b) / 2.0;
Greșelile de finisaj și format
Ultimele, dar nu cele din urmă: detalii care fac diferența între 9 și 10.
9. Formatul greșit al output-ului
Subiectul cere numerele separate prin spațiu, iar tu le scrii pe câte un rând. Sau pui un spațiu în plus la final, sau uiți de endl. Evaluatorul automat compară output-ul exact, caracter cu caracter, așa că un singur spațiu nepotrivit înseamnă răspuns greșit.
Citește cu atenție secțiunea "Date de ieșire" și respect-o la virgulă. Dacă cere "în ordine crescătoare, separate prin câte un spațiu", asta înseamnă fix asta.
10. Cazurile particulare (edge cases)
Programul merge pe exemplul din enunț, dar pică pe cazuri limită: n = 0, un singur element, toate elementele egale, valori negative sau valoarea maximă posibilă. Profesorii care fac testele de BAC adoră aceste cazuri tocmai pentru că mulți elevi le ignoră.
Înainte să te declari mulțumit, testează mental:
- Ce se întâmplă dacă
neste 1? - Ce se întâmplă dacă toate valorile sunt egale?
- Dacă apar numere negative, programul meu funcționează?
- Vectorul gol sau valoarea maximă din constrângeri sparge ceva?
Cum te antrenezi să nu mai faci aceste greșeli
Lista de mai sus nu se învață citind-o o dată. Se învață rezolvând probleme, greșind, apoi recunoscând tiparul. Ține aproape o mică listă de verificare pe care o parcurgi înainte de a preda fiecare subiect:
- Am inițializat toate variabilele (mai ales acumulatorii)?
- Indecșii buclelor sunt corecți (
<vs<=)? - Tipurile de date rezistă la valorile maxime din enunț?
- Citesc din locul corect (tastatură sau fișier) și în formatul corect?
- Output-ul respectă exact formatul cerut?
- Am testat cazurile particulare?
Cinci minute de verificare la final îți pot salva un punct sau două — adesea diferența dintre note.
Concluzie
Greșelile la BAC Informatică nu sunt semn că nu ești bun la programare, ci semne că încă nu ți-ai format reflexele. Toate cele 10 de mai sus se pot transforma din capcane în automatisme, dacă exersezi conștient și înveți să le recunoști din timp.
La ByteSchool lucrăm exact pe aceste tipare: rezolvăm subiecte de BAC împreună, îți arătăm unde apar greșelile clasice și te învățăm să le prinzi singur înainte să predai lucrarea. Cu mentori care au trecut prin aceleași examene și acum lucrează în tech, ajungi la BAC cu reflexele formate, nu cu noroc. Începem de la fundamente și te ducem până la subiectul de 10.