Pagina Modulului 4
Ora 25 - Recapitulare

Recapitulare completă: orele 17 - 24

Sinteza detaliată a tuturor conceptelor din modulul 4, cu definiții, exemple de cod, capcane frecvente și exerciții de antrenament.

75 minute
8 lecții recapitulate
Săptămâna 5
Sigla liceului
Ora 17: Ce este un vector?

Definiția vectorului

Definiție: Un vector (array) este o structură de date care stochează o colecție de elemente de același tip, în locații consecutive de memorie. Fiecare element poate fi accesat direct printr-un indice.

Vectorii sunt folosiți pentru a gestiona ușor colecții de date, cum ar fi notele elevilor, temperaturile dintr-o săptămână, sau orice listă de valori de același tip.

Declararea vectorilor

Sintaxa de bază
tip nume[dimensiune];

unde:

  • tip - tipul de date al elementelor (int, float, char, bool etc.)
  • nume - identificatorul vectorului
  • dimensiune - numărul de elemente (trebuie să fie o constantă)
Exemple
int note[30];           // vector de 30 de numere întregi
float temperaturi[7];   // vector de 7 numere reale
char litere[26];        // vector de 26 de caractere
bool rezultate[100];    // vector de 100 de valori boolene

Declararea cu vector din STL (alternativă)

Pe lângă vectorii clasici (C-style), în C++ putem folosi și vector<int> din biblioteca standard (STL). Aceasta este o alternativă modernă și flexibilă.

Sintaxa vector STL
// Declarare cu dimensiune fixă de 20 de elemente (toate inițializate cu 0)
vector<int> v(20);

// Declarare fără dimensiune (vector gol, se adaugă elemente cu push_back)
vector<int> v;
v.push_back(5);   // adaugă 5 la sfârșit

vector<int> v(n) creează n locuri deja pregătite, pe când vector<int> v; începe gol și trebuie umplut cu push_back.

⚠️ Confuzie frecventă: int v; declară o singură variabilă de tip int, NU un vector! Ca să ai un vector, trebuie neapărat să folosești paranteze pătrate int v[20]; sau STL: vector<int> v(20);. Fără paranteze sau dimensiune, nu poți accesa „căsuțe" cu v[i].

Indexarea vectorilor

Regula fundamentală: În C++, indexarea începe de la 0. Primul element are indicele 0, iar ultimul are indicele dimensiune-1.

int v[5] = {10, 20, 30, 40, 50};
// v[0] = 10 (primul element)
// v[1] = 20
// v[2] = 30
// v[3] = 40
// v[4] = 50 (ultimul element)
// v[5] - ERORĂ! depășirea limitei vectorului
⚠️ Atenție: Accesarea unui element în afara limitelor (de exemplu v[5] pentru un vector cu 5 elemente) duce la comportament imprevizibil și poate cauza erori grave.

Inițializarea vectorilor

Putem inițializa un vector chiar la declarare, folosind acolade.

Metode de inițializare
// 1. Inițializare completă
int a[5] = {10, 20, 30, 40, 50};

// 2. Inițializare parțială (restul devin 0)
int b[10] = {1, 2, 3};   // b[0]=1, b[1]=2, b[2]=3, b[3]...b[9]=0

// 3. Fără dimensiune explicită (compilatorul numără)
int c[] = {2, 4, 6, 8};   // dimensiunea este 4

// 4. Toate elementele cu aceeași valoare
int d[100] = {0};          // toate elementele sunt 0
⚠️ Nu se poate face atribuire după declarare:
int v[5];
v = {1, 2, 3, 4, 5};  // ❌ GREȘIT!

Citirea și afișarea unui vector

De obicei, citim mai întâi numărul de elemente (n), apoi elementele propriu-zise, folosind o buclă for.

Program complet
#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    
    const int MAX = 1000;
    int v[MAX];
    
    // Citire
    for (int i = 0; i < n; i++) {
        cin >> v[i];
    }
    
    // Afișare
    for (int i = 0; i < n; i++) {
        cout << v[i] << " ";
    }
    
    return 0;
}

Pregătire test - Ora 17

  1. Adevărat sau Fals? Pot declara un singur vector care să conțină și note (numere) și numele elevilor (litere) în același timp.
    Fals — vectorul stochează elemente de același tip.
  2. Adevărat sau Fals? Într-un vector cu 5 elemente, primul element se accesează cu v[0], nu cu v[1].
    Adevărat — indexarea începe de la 0.
  3. Adevărat sau Fals? Linia de cod int x; creează o singură variabilă, nu un tablou de valori, deci nu pot scrie x[2].
    Adevărat — int x; este o variabilă simplă, nu un vector.
  4. Adevărat sau Fals? Dacă am declarat int v[5]; pe o linie, pot scrie mai târziu v = {10, 20, 30, 40, 50}; și funcționează.
    Fals — atribuirea cu acolade funcționează doar la declarare.
  5. Alegere multiplă: Care dintre următoarele creează corect un loc pentru 20 de numere întregi?
    a) numbers: array;
    b) int numbers;
    c) vector<int> numbers(20);
    c) vector<int> numbers(20);
  6. Alegere multiplă: Vrem un vector de 100 de elemente, toate cu valoarea 0 din start. Care declarare este corectă?
    a) int v = {0};
    b) v = 0;
    c) int v[100] = {0};
    c) int v[100] = {0};
  7. Completează: Datele dintr-un vector sunt stocate în memorie în locații _______, una după alta.
    consecutive
  8. Completează: Valoarea numerică prin care accesăm un anumit element al vectorului se numește _______.
    indice
  9. Completează: Un vector declarat cu 8 căsuțe are poziții de la 0 la _______.
    7
  10. Completează: Dacă vreau să stochez caractere (litere) într-un vector, folosesc tipul de date _______.
    char
Ora 18: Parcurgerea vectorilor

Ce înseamnă parcurgerea unui vector?

Definiție: Parcurgerea unui vector înseamnă vizitarea fiecărui element al acestuia, de obicei pentru a efectua o operație (citire, afișare, modificare, calcul).

Parcurgerea cu instrucțiunea for (crescător)

Este cea mai folosită metodă. Indexul pornește de la 0 și crește până la n-1.

Modelul standard
for (int i = 0; i < n; i++) {
    // aici lucrăm cu v[i]
}
Exemplu: afișare elemente
i=0afișăm v[0]
i=1afișăm v[1]
......
i=n-1afișăm v[n-1]

Parcurgerea cu instrucțiunea while

Este similară, dar necesită inițializarea și incrementarea manuală a contorului.

Model cu while
int i = 0;
while (i < n) {
    // lucrăm cu v[i]
    i++;  // FOARTE IMPORTANT! Altfel buclă infinită
}
⚠️ Capcană: Dacă uiți instrucțiunea i++, bucla va rula la nesfârșit.

Parcurgerea inversă (descrescător)

Pentru a parcurge vectorul de la ultimul element la primul, folosim un for descrescător.

Parcurgere inversă
for (int i = n - 1; i >= 0; i--) {
    cout << v[i] << " ";
}

// ATENȚIE: i >= 0, nu i > 0! Altfel nu mai afișezi v[0]

Modificarea elementelor în timpul parcurgerii

Putem schimba valorile din vector în aceeași buclă.

Exemple de modificări
// Dublăm toate elementele
for (int i = 0; i < n; i++) {
    v[i] = v[i] * 2;    // sau v[i] *= 2;
}

// Ridicăm la pătrat elementele de pe poziții pare
for (int i = 0; i < n; i += 2) {
    v[i] = v[i] * v[i];
}

// Transformăm negativele în pozitive
for (int i = 0; i < n; i++) {
    if (v[i] < 0) {
        v[i] = -v[i];
    }
}

Operații pe toate elementele

De multe ori parcurgem vectorul pentru a calcula ceva, cum ar fi suma sau numărul de elemente care îndeplinesc o condiție.

Exemple de operații
// Suma elementelor
int suma = 0;
for (int i = 0; i < n; i++) {
    suma += v[i];
}

// Numărul elementelor pare
int cntPare = 0;
for (int i = 0; i < n; i++) {
    if (v[i] % 2 == 0) {
        cntPare++;
    }
}
Tip parcurgere Cod corect Greșeală frecventă
Crescătoare for(i=0; i<n; i++) for(i=1; i<=n; i++) - sare peste v[0] și accesează v[n]
Inversă for(i=n-1; i>=0; i--) for(i=n-1; i>0; i--) - nu afișează v[0]
Cu while i=0; while(i<n) { ... i++; } while(i<n) { ... } - buclă infinită

Pregătire test - Ora 18

  1. Alegere multiplă: Vrem să afișăm elementele unui vector de la ultimul la primul. Care for este corect?
    a) for(int i=n; i>0; i--)
    b) for(int i=n-1; i>=0; i--)
    c) for(int i=0; i<n; i++)
    b) for(int i=n-1; i>=0; i--)
  2. Alegere multiplă: Avem codul: while(i<n) { cout << v[i]; }. Ce problemă are?
    a) Lipsește cin
    b) Lipsește i++
    c) Vectorul nu are acolade
    b) Lipsește i++ — fără el, bucla rulează la infinit.
Ora 19: Minimul și maximul

Definiții

Minimul unui vector este cea mai mică valoare dintre elementele sale.

Maximul unui vector este cea mai mare valoare dintre elementele sale.

Algoritmul pentru găsirea minimului

  1. Inițializăm variabila min cu primul element al vectorului (v[0]).
  2. Parcurgem vectorul de la al doilea element (i=1) până la sfârșit.
  3. Pentru fiecare element, dacă este mai mic decât min, actualizăm min.
Implementare minim
int min = v[0];
for (int i = 1; i < n; i++) {
    if (v[i] < min) {
        min = v[i];
    }
}

Algoritmul pentru găsirea maximului

Similar, dar comparăm cu operatorul >.

Implementare maxim
int max = v[0];
for (int i = 1; i < n; i++) {
    if (v[i] > max) {
        max = v[i];
    }
}

Găsirea simultană a minimului și maximului

Putem găsi ambele valori într-o singură parcurgere, ceea ce este mai eficient.

Min și max simultan
int min = v[0], max = v[0];
for (int i = 1; i < n; i++) {
    if (v[i] < min) min = v[i];
    if (v[i] > max) max = v[i];
}

Determinarea poziției (prima apariție)

Pentru a afla pe ce poziție apare minimul (sau maximul) pentru prima dată, păstrăm și un index.

Minimul și poziția lui
int min = v[0];
int pozMin = 0;

for (int i = 1; i < n; i++) {
    if (v[i] < min) {
        min = v[i];
        pozMin = i;
    }
}
cout << "Minimul " << min << " apare prima dată la poziția " << pozMin;

Determinarea tuturor aparițiilor minimului

Mai întâi găsim valoarea minimă, apoi parcurgem din nou și afișăm toate pozițiile unde apare.

Toate aparițiile minimului
// Găsim minimul
int min = v[0];
for (int i = 1; i < n; i++) {
    if (v[i] < min) min = v[i];
}

// Afișăm toate pozițiile
cout << "Minimul apare la pozițiile: ";
for (int i = 0; i < n; i++) {
    if (v[i] == min) {
        cout << i << " ";
    }
}
⚠️ Capcană fatală: NU inițializa min cu 0 sau cu o valoare arbitrară! De exemplu, dacă toate numerele sunt pozitive și inițializezi min cu 0, minimul va rămâne 0 (greșit). Folosește întotdeauna v[0].
Exemplu: găsire minim pentru v = [8, 3, 10, 2, 7]
Pas 1: min = v[0] = 8
i=1: v[1]=3 < 8? DA → min = 3
i=2: v[2]=10 < 3? NU → min rămâne 3
i=3: v[3]=2 < 3? DA → min = 2
i=4: v[4]=7 < 2? NU → min rămâne 2
Rezultat: min = 2

Pregătire test - Ora 19

  1. Adevărat sau Fals? Când căutăm cel mai mare element dintr-un vector, cel mai sigur mod este să presupunem inițial că elementul de pe prima poziție (v[0]) este cel mai mare.
    Adevărat — inițializăm max cu v[0].
  2. Alegere multiplă: Vrem să aflăm pe ce poziție se află cea mai mică valoare dintr-un vector. Ce informație trebuie să salvăm pe parcurs?
    a) Indicele (poziția)
    b) Suma tuturor elementelor
    c) Doar valoarea minimă
    a) Indicele (poziția)
Ora 20: Verificarea unei proprietăți (flag)

Ce este un flag?

Flag (steguleț) = o variabilă de tip boolean (bool) sau int cu valori 0/1 care reține dacă o anumită proprietate este îndeplinită pentru elementele vectorului. Funcționează ca un „beculeț" — aprins (true) sau stins (false) — care ne spune dacă am găsit sau nu ceea ce căutam.

Tipul de date bool

bool este tipul de date care poate reține doar două valori: true (adevărat) sau false (fals). Este folosit pentru flag-uri, condiții și orice situație în care avem nevoie de un răspuns de tip da/nu.

bool gasit = false;    // inițial nu am găsit nimic
bool esteValid = true; // presupunem că e valid

1. Verificarea "toate elementele au proprietatea P"

Pornim cu flag-ul true și îl facem false dacă găsim un contraexemplu.

Toate elementele sunt pare?
bool toatePare = true;  // presupunem că toate sunt pare

for (int i = 0; i < n; i++) {
    if (v[i] % 2 != 0) {  // dacă găsim un element impar
        toatePare = false;
        break;              // ieșim din buclă (optimizare)
    }
}

if (toatePare) {
    cout << "Toate elementele sunt pare";
} else {
    cout << "Nu toate sunt pare";
}

2. Verificarea "există cel puțin un element cu proprietatea P"

Pornim cu flag-ul false și îl facem true dacă găsim un exemplu.

Există elemente pare?
bool existaPar = false;

for (int i = 0; i < n; i++) {
    if (v[i] % 2 == 0) {
        existaPar = true;
        break;
    }
}

3. Verificarea "niciun element nu are proprietatea P"

Pornim cu flag-ul true și îl facem false dacă găsim un contraexemplu.

Niciun element nu este negativ?
bool niciunNegativ = true;

for (int i = 0; i < n; i++) {
    if (v[i] < 0) {
        niciunNegativ = false;
        break;
    }
}
Întrebare Flag inițial Ce căutăm Când schimbăm flag-ul
Toate elementele au P? true un element care NU are P îl facem false
Există un element cu P? false un element care ARE P îl facem true
Niciun element nu are P? true un element care ARE P îl facem false

4. Verificări cu proprietăți complexe

Pentru proprietăți precum "număr prim" sau "număr perfect", definim funcții separate.

Exemplu: verificare numere prime
// Funcție care verifică dacă un număr este prim
bool estePrim(int x) {
    if (x < 2) return false;
    for (int d = 2; d * d <= x; d++) {
        if (x % d == 0) return false;
    }
    return true;
}

// Verificăm dacă toate elementele sunt prime
bool toatePrime = true;
for (int i = 0; i < n; i++) {
    if (!estePrim(v[i])) {
        toatePrime = false;
        break;
    }
}

// Verificăm dacă există numere prime
bool existaPrim = false;
for (int i = 0; i < n; i++) {
    if (estePrim(v[i])) {
        existaPrim = true;
        break;
    }
}

Pregătire test - Ora 20

  1. Adevărat sau Fals? O variabilă flag funcționează ca un comutator — poate fi doar „da" sau „nu" — și o folosim pentru a ține minte dacă am descoperit ceva anume în vector.
    Adevărat — flag-ul e ca un beculeț: aprins (true) sau stins (false).
  2. Adevărat sau Fals? Poziția unui element în vector (indicele) și valoarea stocată pe acea poziție reprezintă întotdeauna același număr.
    Fals — indicele (i) arată UNDE ești, valoarea (v[i]) arată CE este acolo.
  3. Alegere multiplă: Vrem să verificăm dacă în vector se află măcar un număr divisibil cu 2. Cu ce pornim variabila flag?
    a) 0
    b) true
    c) false
    c) false — pentru „există", pornim cu false și căutăm un exemplu.
  4. Completează: Tipul de variabilă care stochează exclusiv două stări (adevărat sau fals) se numește _______.
    bool
Ora 21: Numărarea elementelor

Ce înseamnă numărarea?

Numărarea elementelor înseamnă parcurgerea vectorului și creșterea unui contor de fiecare dată când un element îndeplinește o condiție specificată.

Modelul general al numărării

Șablon standard
int cnt = 0;  // contorul pornește de la 0

for (int i = 0; i < n; i++) {
    if (condiție(v[i])) {
        cnt++;  // creștem contorul
    }
}

cout << cnt;

Exemple de numărare

Numărare elemente pare și impare
int cntPare = 0, cntImpare = 0;

for (int i = 0; i < n; i++) {
    if (v[i] % 2 == 0) {
        cntPare++;
    } else {
        cntImpare++;
    }
}
Numărare elemente pozitive, negative și zero
int cntPoz = 0, cntNeg = 0, cntZero = 0;

for (int i = 0; i < n; i++) {
    if (v[i] > 0) {
        cntPoz++;
    } else if (v[i] < 0) {
        cntNeg++;
    } else {
        cntZero++;
    }
}

Numărarea în interval [a, b]

Elemente între a și b (inclusiv)
int a, b;
cin >> a >> b;

int cnt = 0;
for (int i = 0; i < n; i++) {
    if (v[i] >= a && v[i] <= b) {
        cnt++;
    }
}

Numărarea aparițiilor unei anumite valori

De câte ori apare x în vector?
int x;
cin >> x;

int cnt = 0;
for (int i = 0; i < n; i++) {
    if (v[i] == x) {
        cnt++;
    }
}

Numărarea cu condiții compuse (AND, OR)

Exemple
// Numără elementele pozitive și pare
int cnt = 0;
for (int i = 0; i < n; i++) {
    if (v[i] > 0 && v[i] % 2 == 0) {
        cnt++;
    }
}

// Numără elementele care sunt zero sau negative
int cnt2 = 0;
for (int i = 0; i < n; i++) {
    if (v[i] <= 0) {  // <= 0 înseamnă negativ sau zero
        cnt2++;
    }
}
⚠️ Atenție la confuzia index/valoare!

if (i % 2 == 0) numără pozițiile pare, nu valorile pare. Pentru valori pare folosim if (v[i] % 2 == 0).

Pregătire test - Ora 21

  1. Adevărat sau Fals? Dacă avem vectorul v = [10, 20, 30] și i=1, atunci i și v[i] au aceeași valoare.
    Fals — i=1, dar v[1]=20. Indicele ≠ valoarea.
  2. Vectorul v = [5, 3, 8, 1]. Dacă i=2, cât este i? Dar v[i]? Sunt egale?
    i=2, v[2]=8. Nu sunt egale.
Ora 22: Calculul unor expresii

Operații matematice de bază pe vectori

Suma elementelor

Suma se calculează adunând pe rând toate elementele. Inițializăm suma cu 0.

Calculul sumei
long long suma = 0;  // folosim long long pentru sume mari

for (int i = 0; i < n; i++) {
    suma += v[i];  // suma = suma + v[i];
}

Produsul elementelor

Produsul se calculează înmulțind toate elementele. Se inițializează cu 1, NU cu 0!

Calculul produsului
long long produs = 1;  // ATENȚIE: se inițializează cu 1, nu cu 0!

for (int i = 0; i < n; i++) {
    produs *= v[i];  // produs = produs * v[i];
}
⚠️ Dacă ai inițializa produsul cu 0, atunci 0 * orice = 0, deci produsul ar fi mereu 0.

Media aritmetică

Media aritmetică = suma elementelor împărțită la numărul de elemente.

Calculul mediei
// Mai întâi calculăm suma
long long suma = 0;
for (int i = 0; i < n; i++) {
    suma += v[i];
}

// Apoi calculăm media (cu zecimale)
double media = (double)suma / n;  // conversie la double pentru împărțire reală

// Afișăm cu 2 zecimale (necesită #include )
cout << fixed << setprecision(2) << media;
⚠️ Caz special: Dacă n = 0, media nu este definită. Trebuie să tratăm această situație separat.

Suma pătratelor

Suma pătratelor = v[0] + v[1] + ... + v[n-1]

Calculul sumei pătratelor
long long sumaPatrate = 0;

for (int i = 0; i < n; i++) {
    sumaPatrate += (long long)v[i] * v[i];  // cast pentru a evita overflow
}

Suma cuburilor

Suma cuburilor = v[0] + v[1] + ... + v[n-1]

Calculul sumei cuburilor
long long sumaCuburi = 0;

for (int i = 0; i < n; i++) {
    sumaCuburi += (long long)v[i] * v[i] * v[i];
}

Calcule selective (cu condiții)

Suma elementelor pare
long long sumaPare = 0;
for (int i = 0; i < n; i++) {
    if (v[i] % 2 == 0) {
        sumaPare += v[i];
    }
}
Media elementelor pozitive
long long sumaPoz = 0;
int cntPoz = 0;

for (int i = 0; i < n; i++) {
    if (v[i] > 0) {
        sumaPoz += v[i];
        cntPoz++;
    }
}

double mediaPoz = (cntPoz > 0) ? (double)sumaPoz / cntPoz : 0;

Pregătire test - Ora 22

  1. Adevărat sau Fals? Când facem suma sau produsul a foarte multor valori, există riscul ca rezultatul să depășească capacitatea tipului int.
    Adevărat — de aceea folosim long long.
  2. Alegere multiplă: Vrem să calculăm produsul tuturor elementelor dintr-un vector. Cu ce valoare trebuie să inițializăm variabila produs?
    a) 1
    b) 0
    c) Primul element din vector
    a) 1 — dacă pornim cu 0, produsul rămâne mereu 0.
  3. Alegere multiplă: Calculăm nota medie a elevilor și vrem rezultat cu zecimale. Ce tip de variabilă folosim pentru medie?
    a) int
    b) double
    c) long long
    b) double — pentru rezultate cu zecimale.
  4. Completează: Ca să acumulăm suma elementelor dintr-un vector, la fiecare pas scriem: s = s + _______;
    v[i]
  5. Completează: Ca să calculăm suma pătratelor elementelor, scriem: s = s + _______;
    v[i] * v[i]
  6. Completează: Când valorile calculate devin foarte mari și depășesc limita lui int, trecem la tipul de date _______.
    long long
Ora 23: Șirul lui Fibonacci

Definiția șirului lui Fibonacci

Șirul lui Fibonacci este definit prin următoarea recurență:

  • F(0) = 0
  • F(1) = 1
  • F(n) = F(n-1) + F(n-2), pentru n ≥ 2

Primii termeni: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...

Generarea primilor n termeni (iterativ)

Folosim trei variabile pentru a memora ultimii doi termeni și termenul curent. Este eficient și nu necesită vector.

Program care afișează primii n termeni Fibonacci
#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    
    if (n <= 0) return 0;
    
    if (n == 1) {
        cout << 0;
        return 0;
    }
    
    if (n == 2) {
        cout << 0 << " " << 1;
        return 0;
    }
    
    long long a = 0, b = 1, c;
    cout << a << " " << b << " ";
    
    for (int i = 2; i < n; i++) {
        c = a + b;
        cout << c << " ";
        a = b;
        b = c;
    }
    
    return 0;
}

Calculul celui de-al n-lea termen (F(n))

Funcție pentru F(n)
long long fibonacci(int n) {
    if (n == 0) return 0;
    if (n == 1) return 1;
    
    long long a = 0, b = 1, c;
    for (int i = 2; i <= n; i++) {
        c = a + b;
        a = b;
        b = c;
    }
    return b;
}
Generare pentru n=6: 0 1 1 2 3 5
Inițial: a=0, b=1
i=2: c = 0+1 = 1 → a=1, b=1
i=3: c = 1+1 = 2 → a=1, b=2
i=4: c = 1+2 = 3 → a=2, b=3
i=5: c = 2+3 = 5 → a=3, b=5

Proprietăți importante

  • Fibonacci poate fi generat fără a folosi un vector, doar cu 3 variabile.
  • Numerele Fibonacci cresc foarte repede. F(47) depășește 2 miliarde (limita int).
  • Raportul dintre doi termeni consecutivi tinde spre numărul de aur φ ≈ 1.618.
⚠️ Overflow: Pentru n > 46, F(n) depășește 2 miliarde. Folosește long long. Pentru n > 90, depășește și long long.

Pregătire test - Ora 23

  1. Adevărat sau Fals? Singura modalitate de a calcula termenii Fibonacci este să-i stocăm pe toți într-un vector.
    Fals — putem folosi doar 2-3 variabile simple, fără vector.
  2. Alegere multiplă: Primii doi termeni din șirul Fibonacci sunt:
    a) 1 și 1
    b) 0 și 2
    c) 0 și 1
    c) 0 și 1 — F(0)=0, F(1)=1.
  3. Completează: În șirul lui Fibonacci, fiecare termen nou se calculează prin _______ celor doi termeni anteriori.
    adunarea
Ora 24: Alte șiruri recurente

Ce este un șir recurent?

Șir recurent = un șir în care fiecare termen este definit pe baza unuia sau mai multor termeni anteriori, printr-o relație de recurență.

Factorialul (n!)

Definiție recurentă:

  • 0! = 1
  • n! = n * (n-1)!, pentru n ≥ 1
Implementare factorial iterativ
long long factorial(int n) {
    long long fact = 1;
    for (int i = 2; i <= n; i++) {
        fact *= i;
    }
    return fact;
}

Primele valori: 0! = 1, 1! = 1, 2! = 2, 3! = 6, 4! = 24, 5! = 120, 6! = 720, ...

Șirul lui Lucas

Definiție:

  • L(0) = 2
  • L(1) = 1
  • L(n) = L(n-1) + L(n-2), pentru n ≥ 2

Este similar cu Fibonacci, dar cu valori inițiale diferite.

Implementare Lucas
long long lucas(int n) {
    if (n == 0) return 2;
    if (n == 1) return 1;
    
    long long a = 2, b = 1, c;
    for (int i = 2; i <= n; i++) {
        c = a + b;
        a = b;
        b = c;
    }
    return b;
}

Primele valori Lucas: 2, 1, 3, 4, 7, 11, 18, 29, 47, 76, ...

Șirul Tribonacci

Definiție:

  • T(0) = 0, T(1) = 0, T(2) = 1
  • T(n) = T(n-1) + T(n-2) + T(n-3), pentru n ≥ 3

Generalizare a lui Fibonacci cu suma ultimilor trei termeni.

Implementare Tribonacci
long long tribonacci(int n) {
    if (n == 0 || n == 1) return 0;
    if (n == 2) return 1;
    
    long long a = 0, b = 0, c = 1, d;
    for (int i = 3; i <= n; i++) {
        d = a + b + c;
        a = b;
        b = c;
        c = d;
    }
    return c;
}

Primele valori Tribonacci: 0, 0, 1, 1, 2, 4, 7, 13, 24, 44, ...

Comparație între Fibonacci și Lucas

n F(n) L(n)
002
111
213
324
437
5511
6818
71329
82147
93476

Relație importantă: L(n) = F(n-1) + F(n+1). Exemplu: L(4) = F(3) + F(5) = 2 + 5 = 7.

Pregătire test - Ora 24

  1. Adevărat sau Fals? Factorialul numărului 0 are valoarea 1, atât în matematică cât și în programare.
    Adevărat — 0! = 1 prin convenție matematică.
  2. Alegere multiplă: Într-un șir de tip Tribonacci, fiecare termen se obține adunând ultimele câte valori?
    a) Două
    b) Trei
    c) Patru
    b) Trei — Tribonacci = suma ultimilor 3 termeni.
  3. Completează: Șirul recurent care seamănă cu Fibonacci dar pornește de la valorile 2 și 1 poartă numele _______.
    Lucas

Descarcă sinteza completă