InfoBook.ro ← Harta anului
Modul 02 · Decizie și repetiție
Modul 02 · Instrucțiuni

Programul care alege și repetă

Cu doar două superputeri — „dacă…atunci" și „repetă cât timp" — poți construi orice algoritm din lume. Serios: orice. Astăzi le stăpânești pe amândouă.

🎯 Obiectiv 1Scrii corect if/else, if/else if și switch — și alegi forma potrivită.
🎯 Obiectiv 2Alegi bucla potrivită: while, do-while sau for — și le convertești între ele.
🎯 Obiectiv 3Urmărești execuția pe schemă + cod + variabile — tehnica nr. 1 la BAC.
1

Decizia: if / else

Programul ajunge la o răscruce, pune o întrebare cu răspuns DA/NU și alege drumul. Rulează-l pas cu pas!

nota =
DA NU START citește nota nota ≥ 5 ? „Promovat" „Corigent" STOP romb = întrebare cu două ieșiri; exact una dintre ramuri se execută
Variabile
nota—
Ecran
 
Alege o notă și apasă „Pas cu pas". 👣
Aceeași idee, trei sintaxe. În C++ condiția stă între paranteze rotunde și blocul între acolade; în Python, două puncte și indentarea obligatorie; în pseudocod, cuvintele „dacă / altfel".

Operatorii cu care pui întrebări (recapitulare din Modulul 01)

RelaționalÎnțeles
<   >   <=   >=comparații obișnuite
==egal? (DOUĂ semne egal!)
!=diferit?
Logic (C++ / Python)Înțeles
&& / andambele condiții adevărate
|| / ormăcar una adevărată
! / notinversează valoarea de adevăr
Greșeala nr. 1 din toate timpurile: if (x = 5) cu un singur egal. Asta nu întreabă „x este 5?", ci atribuie 5 lui x — și condiția devine mereu adevărată. La BAC se punctează diferența!
2

Decizie înlănțuită: if / else if / else

Când drumurile sunt mai mult de două, legăm deciziile în lanț: prima condiție adevărată câștigă, restul nici nu se mai verifică.

Exemplu: categorii de vârstă

v =
DA NU DA NU citește v v < 14 ? „copil" v < 18 ? „adolescent" „adult" STOP prima condiție adevărată câștigă; restul nu se mai verifică deloc
Variabile
v—
Ecran
 
Alege o vârstă și pornește execuția. Încearcă 10, 16 și 40! 👣
De reținut: în lanțul if / else if / else, ordinea condițiilor contează. Dacă puneai întâi „v < 18", un copil de 10 ani ar fi fost etichetat „adolescent" — condiția mai restrictivă vine prima.
3

Selecție multiplă: switch (C++) / match (Python)

Când compari aceeași variabilă cu mai multe valori exacte, ambele limbaje au o poartă cu mai multe ieșiri.

Exemplu: ziua săptămânii după număr — apasă pe o valoare

1Luni
2Marți
3Miercuri
4Joi
5Vineri
6Weekend
7Weekend
altinvalid

switch-ul „deschide" exact ușița potrivită — și linia de cod corespunzătoare se aprinde în ambele limbaje

⚙ C++ — switch

🐍 Python — match (3.10+)

Capcana break (doar C++): fără break, execuția „cade" în case-ul următor — de-asta case 6 și case 7 pot împărți același cod. În Python match nu există căderea: fiecare case e izolat, iar gruparea se face cu | (sau).
Când folosești selecția multiplă? Doar pentru comparații cu valori exacte (1, 2, 'a', 7…). Pentru intervale (v < 14, nota ≥ 5) rămâi la if / else if. default (C++) și case _ (Python) prind tot ce n-a potrivit nimic — plasa de siguranță obligatorie.
🎯 Exersează switch pe pbInfo — Problema „Luna" (#3063) ↗

✅ Exersează structura decizională

După if / else, else-if și switch (secțiunile 1–3), consolidează pe aceste probleme din Lecția 10.1.

✅ Bancă de exerciții pe pbInfo — structura decizională (if) · 18 probleme · click
4

Condiții compuse pe viu: anul bisect

Regula sună ciudat: divizibil cu 4, dar nu cu 100 — sau divizibil cu 400. De unde vine? Din astronomie!

🎯 Exersează pe pbInfo — Problema „bisect" (#177) ↗

🌍 De ce există anii bisecți — povestea din spatele condiției

Un an real (o rotație completă în jurul Soarelui) durează 365,2422 zile — nu fix 365. Dacă am ignora restul, calendarul ar „aluneca": după câteva sute de ani, Crăciunul ar pica vara. Repararea s-a făcut în două etape:

46 î.Hr. · Iulius Cezar O zi în plus la fiecare 4 ani: 29 februarie. media: 365,25 zile/an prea mult cu ~11 minute pe an → o zi întreagă la fiecare ~128 de ani
1582 · Papa Grigore Șterge cele 10 zile deja adunate și scoate 3 bisecți la fiecare 400 de ani: secolele NEdivizibile cu 400. 97 bisecți / 400 ani 1700, 1800, 1900 → NU · 1600, 2000, 2400 → DA
Azi · calendarul gregorian Media coboară aproape perfect pe anul real. media: 365,2425 zile/an abaterea rămasă: o zi întreagă abia la ~3.300 de ani

🧮 Socoteala, în patru rânduri

Cât durează anul real365,2422 zile
Eroarea lui Cezar: 365,25 − 365,2422+0,0078 zile/an → +3,12 zile în 400 de ani
Corecția lui Grigore: scoate 3 bisecți → (400 · 365 + 97) / 400365,2425 zile/an
Eroarea rămasă: 365,2425 − 365,24220,0003 zile/an ≈ 26 s/an
Atenție la unități: „0,0003 zile" și „26 de secunde" sunt aceeași eroare (0,0003 × 24 × 3600 ≈ 26) — pe an. În 400 de ani se adună doar 0,12 zile (~3 ore), de aceea regula nu a mai avut nevoie de alt „petic".
Tradus în logică: bisect = (an % 4 == 0 && an % 100 != 0) || an % 400 == 0
din 4 în 4 ani (Cezar) · MINUS secolele (Grigore) · PLUS secolele divizibile cu 400. Exact condiția compusă pe care o testezi mai jos.
an =
DA NU DA NU DA NU citește an an % 4 == 0 ? an % 100 != 0 ? an%400==0? AN BISECT feb. are 29 zile an obișnuit feb. are 28 zile
an % 4 == 0  (divizibil cu 4? — regula lui Cezar)…
an % 100 != 0  (NU e an de secol?)…
an % 400 == 0  (secol special? — regula lui Grigore)…
 
Alege un an și apasă „Pas cu pas". Încearcă 1900, 2000 și 2024! 👣
Testează cazurile-capcană: 1900 (divizibil cu 4 și cu 100, dar nu cu 400 → NU e bisect) și 2000 (divizibil cu 400 → E bisect). Exact genul de teste de limită despre care am vorbit în Modulul 01!
5

Repetiția: while, do-while, for

Trei unelte pentru aceeași treabă — diferă doar când se verifică condiția și cine numără.

while

Verifică înainte de fiecare pas. Poate să nu execute niciodată corpul.

Folosește-l când nu știi de câte ori repeți: „cât timp mai am cifre…"

do … while

Verifică după. Corpul se execută garantat măcar o dată.

Perfect pentru meniuri și validări. (Nu există în Python — se simulează cu while True + break.)

for

Contor integrat: inițializare, condiție, pas — toate pe o linie.

Folosește-l când știi numărul de repetări: „pentru fiecare i de la 1 la n".

▶ Fiecare buclă, cu schema ei — pas cu pas

n =
Variabile
n—
Ecran
 
Alege o buclă din tab-uri și pornește execuția. 👣

🔁 Conversia for ⇄ while — echivalență cerută la BAC

Același program, scris în două feluri. Cele patru piese sunt aceleași, doar mutate.

cu for

cu while

init pregătirea contorului. În for stă în paranteză; în while, pe o linie înainte de buclă. i = 1
cond cât timp continuăm. Singura piesă care stă în același loc în ambele variante. i <= n
corp ce se execută la fiecare rotație. afișez i
pas creșterea contorului. În for stă în paranteză; în while trebuie pus ultimul în corp — aici se greșește cel mai des. i = i + 1
Aceleași 4 piese — init, cond, corp, pas — doar așezate diferit. La BAC, subiectul II cere frecvent exact această rescriere; verifică mereu că pasul rămâne ultimul în corp.
În Python e ceva mai subtil. Acolo for nu are contor propriu — primește o listă de valori gata făcută de range. Ca să-l rescrii cu while, trebuie să scoți tu contorul la lumină: i = 1 înainte și i = i + 1 la final. Practic, range(1, n + 1) ascunde exact cele trei piese pe care C++ le arată în paranteză.
6

Simulator: suma 1..n, cu tabel de urmărire

Algoritmul-rege al capitolului. Privește cum se rotește bucla în schemă, în cod și în tabelul de urmărire — simultan.

n =
DA NU START citește n s ← 0; i ← 1 i ≤ n ? s ← s + i i ← i + 1 scrie s STOP stânga: corpul (s←s+i; i←i+1) se întoarce la condiție dreapta: pe NU se iese din buclă → scrie s → STOP
Variabile
n—
i—
s—
Ecran
 
verificare i ≤ nis
Apasă „Pas cu pas". Tabelul de urmărire se completează pe măsură ce bucla se rotește. 👣
Tehnica de BAC: la subiectul I primești un pseudocod și un n concret — iar tabelul acesta, făcut pe hârtie, e exact cum obții răspunsul fără să te încurci. Exersează-l până devine reflex.
7

Cele două citiri care apar în absolut orice problemă

Aproape fiecare problemă cu bucle începe la fel: ori citești până apare o valoare-semnal, ori ți se spune dinainte câte numere vin. Învață-le pe amândouă ca tipare — le vei scrie de sute de ori.

① Se citesc numere până la întâlnirea lui 0. Afișează suma lor.

Nu știi dinainte câte numere vin — deci while. Zero e doar semnalul de oprire: nu se adună. Rulează-l pas cu pas și urmărește, în stânga, ce număr din fișier se consumă la fiecare pas.

📄 fișier de intrare · consola
încă n-a citit nimic
necitit acum citit
Variabile
Ecran
 
Apasă „Pas cu pas". 👣
În C++, secretul e citirea dublă. Una înainte de while (ca să ai ce verifica prima dată) și una la finalul corpului (ca să pregătești verificarea următoare). Dacă pui o singură citire, ai una din două: fie condiția verifică o variabilă necitită, fie bucla se învârte la infinit pe același număr. În Python nu există problema asta — ai luat toate numerele dintr-o dată, le parcurgi cu for și ieși cu break.

② Se citește n, apoi n numere. Afișează suma lor.

Aici știi de câte ori repeți — deci for. Numărul n se citește o singură dată, în afara buclei. În fișier, n e pe prima linie și numerele pe a doua — exact cum apare la majoritatea problemelor.

📄 fișier de intrare · consola
încă n-a citit nimic
necitit acum citit
Variabile
Ecran
 
Apasă „Pas cu pas". 👣
O singură variabilă x, refolosită. La fiecare rotație, x primește numărul următor și cel dinainte se pierde — dar nu contează, pentru că l-am adunat deja în suma. Abia la vectori (Modulul 04) vom vrea să le și păstrăm.
Cum le deosebești în enunț: „până la întâlnirea lui 0", „până se citește un număr negativ", „se citesc numere, ultimul fiind 0" → tiparul ①, cu while. „Se citește n și apoi n numere", „primul număr indică câte urmează" → tiparul ②, cu for. Orice altceva e o variantă a acestor două.
🐍 Numai pentru Python — pe ce linie sunt datele? problema cu input(), unealta .split() și simulatorul cu fișier de intrare · sari peste dacă predai C++

🐍 O singură atenție la Python: pe ce linie sunt datele?

Codul de mai sus e corect, dar are o presupunere ascunsă: că fiecare număr stă pe linia lui. Uneori nu e așa — și atunci ai nevoie de o a doua unealtă.

⚙ C++ cin >> x nu-i pasă de linii. Sare peste orice spațiu sau linie nouă și ia următorul număr. Un singur cod merge pe orice așezare a datelor. fără griji
🐍 Python input() citește o linie întreagă, ca text. Dacă pe linie sunt cinci numere, int(input()) se oprește cu eroare — nu poate face un singur număr din „1 2 3 4 5". de ținut minte
!
Enunțul îți spune formatul

Nu trebuie să ghicești. Uită-te la exemplul din „Date de intrare":

1 2 3 4 5 6 0 — toate pe o linie
3 apoi 6 — pe linii separate
4 apoi 2 4 2 1 — și una, și alta

Alegi rețeta după ce vezi acolo. Sunt doar două.

Unealta nouă: .split()

O știi din Modulul 01. Taie o linie în bucăți, după spații:

input() îți dă linia întreagă, ca text: "7 5 3". un text
.split() taie textul la spații și îți dă bucățile: ['7', '5', '3']. Sunt tot texte, nu numere — încă. bucăți de text
for x in linie: trece prin bucăți una câte una. În interior faci x = int(x) și abia atunci ai număr. le iei pe rând

▶ Cele trei rețete, pas cu pas — vezi exact unde se duce fiecare număr

În stânga e fișierul de intrare — ce „tastează" cineva în consolă. Apasă „Pas cu pas" și urmărește cum fiecare bucată din fișier ajunge într-o variabilă.

📄 fișier de intrare · consola
încă n-a citit nimic
necitit se citește acum deja citit
Variabile
Ecran
 
Alege o rețetă și apasă „Pas cu pas". 👣
Uită-te la ghilimele în tabelul de variabile. Când scrie '7', acolo e text, nu număr — și dacă aduni două texte, Python le lipește: „7"+„5" dă „75". Abia după int() dispar ghilimelele și chiar poți calcula. Ăsta e motivul pentru care rețeta ② are încă trei linii după split().
În C++ toate trei arată la fel: cin >> a >> b; — operatorul >> sare singur peste spații și peste linii noi, și face singur transformarea în număr. Python îți cere să faci tu cei doi pași, dar în schimb îți arată exact ce se întâmplă.
Dacă un test nu-ți iese, dar codul pare corect: s-ar putea ca numerele să fie împărțite pe mai multe linii, iar input() a luat doar prima. Atunci citești linie cu linie, în buclă, sau — dacă vrei o soluție care merge orice ar fi în fișier — cauți pe net sys.stdin.read().split(). Nu-ți trebuie anul ăsta; e bine doar să știi că există o plasă de siguranță.

🔁 Exersează structura repetitivă

După while, do-while și for (secțiunile 5–7), antrenează-te pe aceste probleme din Lecția 10.2.

🔁 Bancă de exerciții pe pbInfo — structura repetitivă · 26 de probleme · click
8

O primă privire spre eficiență

Două programe pot da același răspuns muncind foarte diferit. Numără pașii cu noi.

Aceeași problemă — suma numerelor de la 1 la n — rezolvată în două feluri. Pune un n mare (încearcă 1000000) și apasă „Compară".

n =

varianta 1 — cu buclă

—

varianta 2 — cu formula lui Gauss

—
Vocabular nou: spunem că bucla are complexitate O(n) — pașii cresc direct cu n — iar formula are O(1) — un singur pas, indiferent de n. Revenim serios la acest subiect în Modulul 03 (Euclid) și Modulul 08 (sortări).
Atenție la împărțire, în ambele limbaje. În C++, n * (n + 1) / 2 merge pentru că n·(n+1) e mereu par, deci împărțirea întreagă nu pierde nimic — dar pentru n mare ai nevoie de long long, altfel produsul depășește int-ul. În Python trebuie //, nu /: cu un singur slash rezultatul ar ieși 5050.0, cu zecimală, în loc de 5050.
9

Controlul buclei: break și continue

Două cuvinte-cheie care schimbă cursul unei bucle: unul o oprește de tot, celălalt sare peste pasul curent.

break — iese complet din buclă pe loc, chiar dacă for/while ar mai continua. Util când ai găsit ce căutai și nu mai are rost să cauți mai departe.
continue — sare peste restul pasului curent și trece direct la iterația următoare. Util când vrei să ignori anumite valori.

🔎 break — caută dacă x apare printre n numere, oprește-te la prima găsire

Fără break ai parcurge tot șirul degeaba; cu break te oprești imediat ce l-ai găsit.

n = x = șirul

n e prima valoare din fișierul de intrare — câte numere urmează. Crește-l și în șir apare un număr nou; scade-l și ultimul dispare. Șirul are mereu exact n valori, exact ca în datele unei probleme.

DA NU DA NU citește n, x gasit ← fals i ≤ n ? citește a a = x ? i ← i + 1 gasit ← adevărat · BREAK scrie DA / NU break sare direct la ieșire, fără să mai treacă prin i ← i + 1
Variabile
n—
x—
i—
a—
gasit—
Ecran
 
ia citita = x ?
Pune un x și un șir, apoi apasă „Pas cu pas". Încearcă un x care NU apare! 👣
Ce trebuie să observi: când break se execută, săgeata pleacă direct spre ieșire — nu mai trece prin i ← i + 1 și nici prin verificarea condiției. De-asta numărul de pași e mai mic când valoarea e găsită devreme.

➕ continue — adună doar numerele pare, sări peste cele impare

Când întâlnești un număr impar, continue te trimite direct la următorul, fără să-l aduni.

n = șirul

n e prima valoare din fișierul de intrare — câte numere urmează. Crește-l și în șir apare un număr nou; scade-l și ultimul dispare. Șirul are mereu exact n valori, exact ca în datele unei probleme.

DA NU DA NU continue citește n suma ← 0 i ≤ n ? citește a a impar ? suma ← suma + a i ← i + 1 scrie suma
Variabile
n—
i—
a—
suma—
Ecran
 
a cititimpar?suma
Pune un șir și apasă „Pas cu pas". Urmărește ce se întâmplă la numerele impare. 👣
Diferența față de break: continue nu iese din buclă — sare doar peste restul corpului și ajunge la i ← i + 1. Bucla se rotește mai departe, exact de tot atâtea ori. De-asta săgeata portocalie coboară în „i ← i + 1", nu în afara schemei.
De reținut: break = „gata, ies din buclă"; continue = „sar peste acest pas". Amândouă acționează asupra buclei celei mai apropiate în care se află. Le folosești des la căutări (break la prima potrivire) și la filtrări (continue peste valorile nedorite).
10

Vânătoarea de bug-uri

Cinci programe, cinci erori pe care le vezi în fiecare an la teze și la BAC. Click pe linia vinovată din fiecare.

🐞 Bug 1: programul ar trebui să afișeze cel mai mare dintre a și b

🐞 Bug 2: programul ar trebui să afișeze numerele de la 1 la 5 — dar nu se oprește niciodată!

🐞 Bug 3: ar trebui să afișeze 1 2 3 4 5 — dar afișează un singur număr

🐞 Bug 4: suma primelor n numere — dar rezultatul iese mereu egal cu n

🐞 Bug 5: media a două note — pentru 7 și 8 afișează 7, nu 7.5

11

Ce afișează codul?

Zece întrebări în stil BAC, fiecare construită pe o greșeală clasică: împărțire întreagă, punct-și-virgulă rătăcit, off-by-one, = în loc de ==, post-incrementare. Fă tabelul de urmărire pe hârtie înainte să alegi — variantele sunt amestecate la fiecare încărcare.

12

Fișa de sinteză

Ideile-temelie ale întregului an.

if (condiție) … else … — drumuri alternative; condiția e o expresie logică (adevărat/fals).
== compară, = atribuie. Confuzia dintre ele e cea mai frecventă eroare la începători și la BAC.
while = nu știu de câte ori; for = știu de câte ori; do-while = măcar o dată (doar C++).
Orice for ⇄ while: init; while(cond){ corp; pas; } — echivalență cerută la examen.
Bucla infinită apare când condiția nu devine niciodată falsă — verifică mereu cine modifică contorul.
Tabelul de urmărire (i, s, condiție) e unealta cu care „rulezi" programe pe hârtie.
if / else if / else: prima condiție adevărată câștigă — pune condiția mai restrictivă prima.
switch (C++) / match (Python 3.10+) — pentru valori exacte; fără break, C++ „cade" în case-ul următor.
Anul bisect: (an%4==0 && an%100!=0) || an%400==0 — regula lui Cezar, rafinată de Grigore în 1582.
Eficiență: O(n) = pașii cresc cu n; O(1) = constant. Algoritmul ales contează, nu doar rezultatul.
Exersează pe pbinfo.ro: categoriile „Structura alternativă" și „Structura repetitivă" — minimum 8 probleme. Începe cu maximul a 3 numere și seria despre divizibilitate.
🔒

Rezolvările problemelor din cele două bănci

Toate cele 44 de probleme linkate mai sus, rezolvate în C++ și Python, cu aceleași metode predate în lecție. Zonă pentru profesor.

🔒

Rezolvările sunt pentru profesor. Elevii au mai sus enunțurile și toate uneltele de care au nevoie.

← anteriorModul 01 · Principiile unui program urmează →Modul 03 · Prelucrarea numerelor