Invatare Atomica

Introducere in matrice (tablouri bidimensionale)

Incadrare in programa: Tabloul bidimensional nu este o unitate de continut explicita in programa cls. X mat-info. Aceasta lectie este inclusa ca lectie-punte necesara pentru Domeniu 1 — Modele neliniare (arbore binar, graf), unde reprezentarea prin matrice de adiacenta este fundamentala. Tablourile unidimensionale au fost studiate la cls. IX (unitatea 3.6); extinderea la 2D este un pas natural inainte de structuri de date avansate. Ordinea si adancimea de tratare raman la latitudinea profesorului conform proiectiei curriculare.

Progres lectie:
0%
🎯

Obiectivul lectiei

Vei intelege ce este un tablou bidimensional (matrice), cum se declara si se initializeaza in Python (si in C++ la intensiv), si vei invata sa parcurgi o matrice pe linii si pe coloane cu bucle imbricate.

Dupa aceasta lectie vei putea:

  • Sa definesti conceptul de matrice ca tablou bidimensional indexat prin (linie, coloana)
  • Sa declari si sa initializezi o matrice in Python (lista de liste) si in C++ (tablou 2D)
  • Sa accesezi elementul de pe linia i, coloana j: a[i][j]
  • Sa parcurgi o matrice pe linii (i exterior, j interior) si pe coloane (j exterior, i interior)
  • Sa calculezi complexitatea O(n*m) a parcurgerii complete a unei matrice
  • Sa rezolvi probleme clasice: suma pe linie, maxim pe coloana, afisare formatata

Incearca singur!

Provocare:

Gandeste-te la un catalog scolar cu 3 elevi si 4 note fiecare. Cum ai organiza aceste date intr-o structura? Scrie cele 12 valori pe hartie, aranjate pe 3 randuri a cate 4 coloane.

💡 Ai nevoie de un indiciu?

Aranjamentul tau pe linii si coloane este exact o matrice! Fiecare rand = o linie a matricei, fiecare coloana = o coloana a matricei. Accesezi o nota cu: catalog[elev][nota].

1

1. Ce este o matrice?

O matrice (tablou bidimensional) este o colectie de elemente aranjate pe linii si coloane. Fiecare element este identificat prin doua indici: (i, j) unde i = linia si j = coloana. Indexarea incepe de la 0 in Python si C++.
Vizualizare matrice 3x3 (3 linii, 3 coloane):
         col 0  col 1  col 2
linia 0:   1      2      3
linia 1:   4      5      6
linia 2:   7      8      9

a[0][0]=1  a[0][1]=2  a[0][2]=3
a[1][0]=4  a[1][1]=5  a[1][2]=6
a[2][0]=7  a[2][1]=8  a[2][2]=9
Terminologie esentiala:
  • Dimensiuni: o matrice cu n linii si m coloane se noteaza n×m si are n*m elemente.
  • Matrice patratica: n = m (numar egal de linii si coloane).
  • Diagonala principala: elementele a[i][i] cu i=0..n-1, de sus-stanga la jos-dreapta.
  • Diagonala secundara: elementele a[i][n-1-i], de sus-dreapta la jos-stanga.
2

2. Declarare si initializare in Python

In Python, o matrice se reprezinta ca o lista de liste. Fiecare element al listei exterioare este o linie (si ea o lista).
# Declarare si initializare matrice 3x3
matrice = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]
print("Matrice 3x3:")
for i in range(3):
    for j in range(3):
        print(matrice[i][j], end=" ")
    print()
Output real (python mat_py1.py):
Matrice 3x3:
1 2 3
4 5 6
7 8 9 
Initializare dinamica — recomandata pentru matrice de zerouri de dimensiuni n×m:
# Matrice nxm cu toate elementele 0
n, m = 3, 4
# CORECT: list comprehension - fiecare linie e un obiect distinct
matrice = [[0] * m for _ in range(n)]
# ATENTIE: [[0]*m]*n este GRESIT - toate liniile sunt acelasi obiect
De ce [[0]*m]*n este o capcana?

Operatorul * pe o lista copiaza referinte, nu obiecte noi. Daca modifici a[0][1], se modifica si a[1][1], a[2][1] etc. — pentru ca toate liniile indica acelasi obiect. List comprehension [[0]*m for _ in range(n)] creeaza linii complet independente.

3

3. Parcurgere pe linii

La parcurgerea pe linii, bucla exterioara itereaza liniile (i), iar bucla interioara itereaza coloanele (j). Elementele sunt vizitate in ordine: linia 0 de la stanga la dreapta, apoi linia 1, etc.
# Parcurgere pe linii si calculul sumei fiecarei linii
matrice = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]
print("Suma pe fiecare linie:")
for i in range(3):
    suma_linie = 0
    for j in range(3):
        suma_linie += matrice[i][j]
    print(f"  Linia {i}: suma = {suma_linie}")
Output real (python mat_py2.py):
Suma pe fiecare linie:
  Linia 0: suma = 6
  Linia 1: suma = 15
  Linia 2: suma = 24
Complexitate temporala:

Bucla exterioara face n iteratii, bucla interioara face m iteratii. Total: n*m operatii elementare. Complexitate: O(n*m). Pentru o matrice patratica n×n: O(n²).

4

4. Parcurgere pe coloane

La parcurgerea pe coloane, bucla exterioara itereaza coloanele (j), iar bucla interioara itereaza liniile (i). Elementele sunt vizitate de sus in jos pe coloana 0, apoi pe coloana 1, etc.
# Parcurgere pe coloane si calculul maximului fiecarei coloane
matrice = [
    [3, 7, 2],
    [8, 1, 9],
    [4, 6, 5]
]
print("Maximul pe fiecare coloana:")
for j in range(3):
    maxim_col = matrice[0][j]
    for i in range(1, 3):
        if matrice[i][j] > maxim_col:
            maxim_col = matrice[i][j]
    print(f"  Coloana {j}: maxim = {maxim_col}")
Output real (python mat_py3.py):
Maximul pe fiecare coloana:
  Coloana 0: maxim = 8
  Coloana 1: maxim = 7
  Coloana 2: maxim = 9
Urmareste executia pas cu pas (coloana 0):
  • Initializam maxim_col = matrice[0][0] = 3
  • i=1: matrice[1][0] = 8 > 3 → maxim_col = 8
  • i=2: matrice[2][0] = 4 < 8 → nu se modifica
  • Rezultat coloana 0: maxim = 8
5

5. Matrice nepatratica si afisare formatata

O matrice nu trebuie sa fie patratica. O matrice n×m cu n ≠ m este perfect valida. Afisarea formatata (coloane aliniate) imbunatateste lizibilitatea rezultatelor.
# Matrice 3x4 generata prin formula, afisata aliniat
n, m = 3, 4
matrice = [[i * m + j + 1 for j in range(m)] for i in range(n)]
print(f"Matrice {n}x{m}:")
for i in range(n):
    for j in range(m):
        print(f"{matrice[i][j]:4}", end="")
    print()
print(f"Total elemente: {n * m}")
Output real (python mat_py4.py):
Matrice 3x4:
   1   2   3   4
   5   6   7   8
   9  10  11  12
Total elemente: 12
Explicatie format f"{x:4}":

Specificatorul :4 rezerva 4 caractere pentru valoare, cu aliniere la dreapta. Numerele de 1 sau 2 cifre sunt precedate de spatii, astfel coloanele se aliniaza vizual.

6

6. Tablouri 2D in C++ EXCLUSIV INTENSIV

⚡ Sectiune doar pentru intensiv informatica

In C++, tabloul bidimensional se declara cu tipul explicit si dimensiunile cunoscute la compilare. Sintaxa: tip_element nume[NR_LINII][NR_COLOANE];. Se recomanda constante const int in loc de literale numerice directe.

#include <iostream>
using namespace std;
int main() {
    // Declarare matrice 3x3 cu initializare explicita
    int a[3][3] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };
    cout << "Matrice 3x3:" << endl;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            cout << a[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}
Output real (g++ -std=c++17 mat_cpp1.cpp -o mat_cpp1.exe && mat_cpp1.exe):
Matrice 3x3:
1 2 3
4 5 6
7 8 9 

Parcurgere pe coloane cu maxim per coloana — aceeasi logica ca in Python, cu sintaxa C++:

#include <iostream>
using namespace std;
int main() {
    const int N = 3, M = 3;
    int a[N][M] = {{3,7,2},{8,1,9},{4,6,5}};
    cout << "Maximul pe fiecare coloana:" << endl;
    for (int j = 0; j < M; j++) {
        int maxim = a[0][j];
        for (int i = 1; i < N; i++)
            if (a[i][j] > maxim) maxim = a[i][j];
        cout << "  Coloana " << j << ": maxim = " << maxim << endl;
    }
    return 0;
}
Output real (g++ -std=c++17 mat_cpp2.cpp -o mat_cpp2.exe && mat_cpp2.exe):
Maximul pe fiecare coloana:
  Coloana 0: maxim = 8
  Coloana 1: maxim = 7
  Coloana 2: maxim = 9
Diferente fata de Python:
  • Tipul elementelor (int) se declara explicit la fiecare variabila.
  • Dimensiunile trebuie cunoscute la compilare (constante, nu variabile calculate la runtime).
  • Nu exista capcana "referinte la acelasi obiect" — tabloul C++ aloca memorie continua in mod direct.
  • Fiecare instructiune se termina obligatoriu cu ;.

Exercitii practice

Exercitiul 1 (Nivel minim) — Afisare matrice

Declara in Python o matrice 2x3 cu valorile: prima linie [10, 20, 30], a doua linie [40, 50, 60]. Afiseaz-o element cu element pe linii si afiseaza numarul total de elemente.

Rezultat asteptat: 6 valori afisate pe 2 randuri, si mesajul "Total: 6".

Vezi rezolvarea

Rezolvare: matricea e o lista de liste, exact ca la Atomul 2 din lectie.

  1. Declarare: matrice = [[10, 20, 30], [40, 50, 60]]
  2. Parcurgere pe linii (i exterior, j interior), ca la Atomul 3: for i in range(2): for j in range(3): print(matrice[i][j], end=" ") ; print()
  3. Numarul total de elemente: print("Total:", len(matrice) * len(matrice[0])) — sau simplu 2 * 3.

Rezultat pe ecran: linia 0 afiseaza 10 20 30, linia 1 afiseaza 40 50 60, apoi Total: 6.

Exercitiul 2 (Nivel standard) — Suma totala si media

Fie matricea: [[5, 3, 8], [2, 7, 1], [9, 4, 6]]. Scrie un program Python care calculeaza suma tuturor elementelor (parcurgere pe linii) si media aritmetica. Verifica: suma = 45, media = 5.0.

Vezi rezolvarea

Rezolvare: folosim parcurgerea pe linii din Atomul 3, cu un acumulator general pentru toata matricea.

  1. Declarare: matrice = [[5, 3, 8], [2, 7, 1], [9, 4, 6]]
  2. Acumulam suma cu doua bucle imbricate: suma = 0, apoi for i in range(3): for j in range(3): suma += matrice[i][j]
  3. Numarul de elemente este 3*3 = 9, deci media este media = suma / 9.
  4. Afisare: print("Suma:", suma) si print("Media:", media)

Verificare: suma = 45, media = 45 / 9 = 5.0 — exact cifrele din cerinta.

Exercitiul 3 (Nivel performanta) — Minimul pe linii si coloane

Scrie un program Python (si in C++ la intensiv) pentru o matrice 4x4 cu valori alese de tine. Programul trebuie sa afiseze: (a) minimul fiecarei linii; (b) minimul fiecarei coloane; (c) minimul global al intregii matrice. Verifica rezultatele manual inainte de rulare.

Vezi rezolvarea

Schita de rezolvare (nu solutia gata facuta — o completezi tu):

  1. Alege o matrice 4x4 cu valori proprii, ca lista de liste (Atomul 2).
  2. Minim pe fiecare linie: adapteaza tiparul de la Atomul 4 (acolo era maxim pe coloana) — bucla exterioara pe i, interioara pe j, initializezi cu matrice[i][0] si compari cu < in loc de >.
  3. Minim pe fiecare coloana: foloseste structura exacta din Atomul 4 (j exterior, i interior), doar schimbi > in <.
  4. Minim global: o singura variabila actualizata in dubla bucla de la Atomul 3, sau scurtatura min(min(linie) for linie in matrice).
  5. Pentru intensiv (C++): tablou int a[4][4], aceleasi trei bucle, sintaxa din Atomul 6.

Capcana: nu initializa minimul cu 0 daca ai valori negative in matrice. Criterii de evaluare: cele trei rezultate corecte, complexitate O(n*m), cod fara duplicare inutila, verificare manuala inainte de rulare (ceruta explicit).

Ce ai invatat astazi

  • O matrice n×m are n linii, m coloane si n*m elemente; accesul se face prin a[i][j] (i=linia, j=coloana), indexat de la 0
  • In Python: matrice = lista de liste; initializare sigura: [[0]*m for _ in range(n)]
  • Parcurgere pe linii: i exterior, j interior — utila pentru operatii pe randuri (suma, maxim pe linie)
  • Parcurgere pe coloane: j exterior, i interior — utila pentru operatii pe coloane (maxim, minim per coloana)
  • Complexitatea parcurgerii complete: O(n*m); pentru matrice patratica: O(n²)
  • In C++ (intensiv): int a[N][M], dimensiuni la compilare, fara capcane de referinte

Vrei mai mult?

Provocare: Scrie un program Python care roteste o matrice patrata cu 90 de grade in sens orar, fara nicio biblioteca externa. Testeaza cu matricea din lectie, [[1,2,3],[4,5,6],[7,8,9]] — rezultatul trebuie sa fie [[7,4,1],[8,5,2],[9,6,3]].

Intrebare de gandit: Parcurgerea pe linii si cea pe coloane fac exact acelasi numar de operatii, n*m, deci ar trebui sa fie la fel de rapide. In practica, pe matrice foarte mari, parcurgerea pe linii e de obicei mai rapida. Gandeste-te cum sunt asezate in memorie elementele unei liste de liste — poti ghici de ce?

Deschidere: O imagine alb-negru e, la baza, o matrice: a[i][j] e valoarea de gri a pixelului de pe linia i, coloana j. Editarea unei poze (contrast, blur) inseamna parcurgerea acestei matrice si recalcularea fiecarui a[i][j] dupa o formula — exact bucla dubla de azi, aplicata la milioane de pixeli.

Urmatoarea lectie

Continua cu Lectia 5: Operatii pe matrice — diagonale, zone speciale, transpunere.

Continua →