Școala Româno-Britanică
Modulul 3 Clasa a X-a | C++

Ora 2: Parcurgerea matricei și prelucrări de bază

Ce vei învăța astăzi: Parcurgerea matricei cu două bucle for, suma elementelor, minimul și maximul

Rezultat practic: Parcurgi o matrice cu bucle imbricate (adică bucle for aflate una în interiorul celeilalte) și calculezi suma, minimul și maximul elementelor în C++ (Competența 2.4).

Competența 2.4 Săptămâna 12

Înainte de a începe

De ce contează? Suma, minimul și maximul unei matrice sunt primele prelucrări cerute la aproape orice problemă de BAC cu tablouri bidimensionale - și le vei folosi și la proiectul modulului, pentru mediile și nota maximă a elevilor.

Ce știi deja?

La ora 1 ai citit și afișat o matrice cu două bucle for. Acum folosești exact aceleași bucle, dar în loc să afișezi elementul, faci o operație cu el: adunare, comparație sau numărare. Poți spune de ce bucla exterioară parcurge liniile?

Ideea-cheie: Orice prelucrare de bază - sumă, minim, maxim, numărare - se obține cu o singură parcurgere a matricei: în bucla interioară adaugi doar instrucțiunea potrivită (acumulare, comparație sau contorizare).
SINTEZĂ TEORETICĂ ȘI EXEMPLE GHIDATE

Ce vei învăța astăzi?

După această lecție vei ști să parcurgi o matrice cu două bucle for și să aplici prelucrări de bază: suma elementelor, determinarea minimului și maximului.

Parcurgerea matricei cu două bucle for
Suma elementelor matricei
Determinarea minimului și maximului
Numărarea elementelor cu o proprietate

Parcurgerea matricei cu două bucle for

Definiție: A parcurge o matrice înseamnă a vizita fiecare element exact o dată. Pentru aceasta folosim două bucle for imbricate: bucla exterioară parcurge liniile, iar cea interioară coloanele.

Exemplu: numărăm elementele pozitive

Program complet
#include <iostream>
using namespace std;

int main() {
    int m, n, a[101][101], i, j, cnt = 0;
    cin >> m >> n;

    for (i = 1; i <= m; i++)
        for (j = 1; j <= n; j++)
            cin >> a[i][j];

    for (i = 1; i <= m; i++)
        for (j = 1; j <= n; j++)
            if (a[i][j] > 0)
                cnt++;

    cout << cnt;
    return 0;
}

Observă: contorul cnt (variabila care numără elementele ce îndeplinesc o condiție) se inițializează cu 0 înainte de parcurgere și crește cu 1 la fiecare element care îndeplinește condiția.

Suma elementelor matricei

Pentru a calcula suma tuturor elementelor matricei inițializăm suma cu 0, apoi parcurgem matricea și adunăm fiecare element: s = s + a[i][j].

Program complet: suma elementelor
#include <iostream>
using namespace std;

int main() {
    int m, n, a[101][101], i, j, s = 0;
    cin >> m >> n;

    for (i = 1; i <= m; i++)
        for (j = 1; j <= n; j++)
            cin >> a[i][j];

    for (i = 1; i <= m; i++)
        for (j = 1; j <= n; j++)
            s = s + a[i][j];

    cout << s;
    return 0;
}

Observă: variabila s este o dată de manevră (o variabilă auxiliară care acumulează rezultate pe parcursul prelucrării) care acumulează suma pe măsură ce parcurgem matricea.

Minimul și maximul din matrice

Pentru a găsi maximul (sau minimul) din matrice, inițializăm variabila cu primul element a[1][1], apoi parcurgem matricea și actualizăm valoarea de fiecare dată când întâlnim un element mai mare (respectiv mai mic).

Algoritmul MaximMatrice(m, n): // pasul 1: citirea matricei pentru i = 1, m execută pentru j = 1, n execută citește a[i][j] sfârșit pentru sfârșit pentru // pasul 2: inițializarea maximului cu primul element maxi <- a[1][1] // pasul 3: parcurgerea întregii matrice pentru i = 1, m execută pentru j = 1, n execută dacă a[i][j] > maxi atunci maxi <- a[i][j] sfârșit dacă sfârșit pentru sfârșit pentru // pasul 4: afișarea rezultatului scrie maxi
Program complet: maximul din matrice
#include <iostream>
using namespace std;

int main() {
    int m, n, a[101][101], i, j, maxi;
    cin >> m >> n;

    for (i = 1; i <= m; i++)
        for (j = 1; j <= n; j++)
            cin >> a[i][j];

    maxi = a[1][1];
    for (i = 1; i <= m; i++)
        for (j = 1; j <= n; j++)
            if (a[i][j] > maxi)
                maxi = a[i][j];

    cout << maxi;
    return 0;
}

Observă: pentru minim folosim aceeași idee, dar cu operatorul <. Putem afișa ambele valori cu cout << maxi << " " << mini.

Exercițiu de completare

Completează enunțul cu cuvintele potrivite:

Pentru a parcurge o matrice cu m linii și n coloane folosim ______ bucle for imbricate. Variabila ______ parcurge liniile, iar variabila ______ parcurge coloanele.

Bancă de cuvinte:
două i j o

Exercițiu de completare 2

Completează afirmațiile despre sumă și maxim:

Înainte de calcul, suma se inițializează cu ______. Fiecare element se adaugă cu ______. Maximul se inițializează cu ______, primul element al matricei.

Bancă de cuvinte:
0 s = s + a[i][j] a[1][1] 1

Test de înțelegere

Test rapid - prelucrări de bază:

1. Pentru a parcurge toate elementele unei matrice folosim:

2. Suma elementelor se inițializează cu:

3. Maximul din matrice se inițializează, de obicei, cu:

Ai grijă la: maximul inițializat cu 0: la o matrice cu valori negative nu ai mai găsi elementul maxim. Inițializează maximul cu primul element al matricei, a[1][1], înainte de parcurgere.

Aprofundare

Poziția maximului și nu doar valoarea: de foarte multe ori problema cere și unde se află maximul, nu doar cât este el. În acest caz memorăm, pe lângă valoare, linia lmax și coloana cmax, actualizate doar atunci când găsim un element mai mare. Dacă folosim condiția strictă >, păstrăm prima apariție; dacă folosim >=, păstrăm ultima apariție. Este o nuanță pe care baremele de la BAC o punctează adesea.

Suma cu long long pentru valori mari: dacă matricea are 100 de linii și 100 de coloane, iar elementele pot fi până la un miliard, suma poate ajunge la 10^13, ceea ce nu mai încape într-un int. Pentru astfel de cazuri declarați suma long long s = 0;. Aceeași regulă se aplică și la numărarea unor cantități foarte mari.

Inițializarea maximului - capcana clasică: inițializarea cu a[1][1] este corectă pentru orice matrice nevidă. Inițializarea cu 0 este o greșeală dacă matricea poate conține doar valori negative, pentru că atunci maximul ar rămâne 0, deși nu apare în matrice. Regula generală: pentru maxim folosim primul element sau cea mai mică valoare posibilă; pentru minim, primul element sau cea mai mare valoare posibilă.

Contorizarea elementelor cu o proprietate: ori de câte ori numărăm elemente care îndeplinesc o condiție (pozitive, pare, mai mari decât o valoare), inițializăm contorul cu 0 înainte de parcurgere și îl incrementăm cu 1 doar în interiorul if-ului. Contorul este o dată de manevră - nu se citește și nu se afișează până la final.

APLICARE ȘI REZOLVARE DE PROBLEME

PbInfo - Suma elementelor unei matrice

Enunț:

Cerință: Se citește o matrice cu m linii și n coloane. Să se afișeze suma tuturor elementelor matricei.

Date de intrare:

Programul citește de la tastatură numerele m și n, apoi elementele matricei, linie cu linie.

Date de ieșire:

Programul va afișa pe ecran suma elementelor matricei.

Restricții și precizări:

1 <= m, n <= 100, elementele matricei sunt numere întregi, iar suma se încadrează în long long.

Exemplu:

Intrare:

2 3
1 2 3
4 5 6

Ieșire:

21
Cum gândim soluția:
  1. Inițializăm suma cu 0
  2. Parcurgem matricea cu două bucle for
  3. Adunăm fiecare element: s = s + a[i][j]
  4. Afișăm suma finală
Scrie soluția în C++:
Soluție corectă:
Soluția completă
#include <iostream>
using namespace std;

int main() {
    int m, n, a[101][101], i, j, s = 0;
    cin >> m >> n;

    for (i = 1; i <= m; i++)
        for (j = 1; j <= n; j++)
            cin >> a[i][j];

    for (i = 1; i <= m; i++)
        for (j = 1; j <= n; j++)
            s = s + a[i][j];

    cout << s;
    return 0;
}

Ce învățăm: suma se acumulează într-o variabilă inițializată cu 0, adunând fiecare element în timpul parcurgerii.

PbInfo - Maximul și minimul dintr-o matrice

Enunț:

Cerință: Se citește o matrice cu m linii și n coloane. Să se afișeze valoarea maximă și valoarea minimă din matrice, separate printr-un spațiu.

Date de intrare:

Programul citește de la tastatură numerele m și n, apoi elementele matricei, linie cu linie.

Date de ieșire:

Programul va afișa maximul și minimul matricei, separate printr-un spațiu.

Restricții și precizări:

1 <= m, n <= 100, elementele matricei sunt numere întregi.

Exemplu:

Intrare:

2 3
1 2 3
4 5 6

Ieșire:

6 1
Cum gândim soluția:
  1. Inițializăm maxi și mini cu primul element a[1][1]
  2. Parcurgem matricea cu două bucle for
  3. Dacă elementul este mai mare decât maxi, îl actualizăm; la fel pentru minim
  4. Afișăm cele două valori
Scrie soluția în C++:
Soluție corectă:
Soluția completă
#include <iostream>
using namespace std;

int main() {
    int m, n, a[101][101], i, j, maxi, mini;
    cin >> m >> n;

    for (i = 1; i <= m; i++)
        for (j = 1; j <= n; j++)
            cin >> a[i][j];

    maxi = a[1][1];
    mini = a[1][1];

    for (i = 1; i <= m; i++)
        for (j = 1; j <= n; j++) {
            if (a[i][j] > maxi)
                maxi = a[i][j];
            if (a[i][j] < mini)
                mini = a[i][j];
        }

    cout << maxi << " " << mini;
    return 0;
}

Ce învățăm: maximul și minimul se determină într-o singură parcurgere, actualizând cele două variabile cu if.

EXERCIȚII PRACTICE

Exercițiul Practic: Prelucrări de bază pe matrice

Sarcini de lucru

Completează următoarele sarcini pentru a-ți consolida parcurgerea și prelucrarea matricei

Sarcina 1: Numără elementele pare

Cerință: Scrie un program C++ care citește o matrice cu m linii și n coloane și afișează câte elemente pare conține.

Soluție pentru Sarcina 1:
#include <iostream>
using namespace std;

int main() {
    int m, n, a[101][101], i, j, cnt = 0;
    cin >> m >> n;

    for (i = 1; i <= m; i++)
        for (j = 1; j <= n; j++)
            cin >> a[i][j];

    for (i = 1; i <= m; i++)
        for (j = 1; j <= n; j++)
            if (a[i][j] % 2 == 0)
                cnt++;

    cout << cnt;
    return 0;
}

Verifică: un număr este par dacă restul împărțirii la 2 este 0, adică a[i][j] % 2 == 0.

Sarcina 2: Găsește poziția maximului

Cerință: Scrie un program C++ care citește o matrice cu m linii și n coloane și afișează linia și coloana primei apariții a maximului, separate printr-un spațiu.

Soluție pentru Sarcina 2:
#include <iostream>
using namespace std;

int main() {
    int m, n, a[101][101], i, j, maxi, lmax = 1, cmax = 1;
    cin >> m >> n;

    for (i = 1; i <= m; i++)
        for (j = 1; j <= n; j++)
            cin >> a[i][j];

    maxi = a[1][1];
    for (i = 1; i <= m; i++)
        for (j = 1; j <= n; j++)
            if (a[i][j] > maxi) {
                maxi = a[i][j];
                lmax = i;
                cmax = j;
            }

    cout << lmax << " " << cmax;
    return 0;
}

Verifică: folosim condiția strictă >, așa că prima apariție a maximului este păstrată; lmax și cmax memorează poziția.

Scrie pe caiet - De reținut

Titlul lecției

Ora 2: Parcurgerea matricei și prelucrări de bază

Definiția lecției

A parcurge o matrice înseamnă a vizita fiecare element exact o dată, folosind două bucle for imbricate: bucla exterioară parcurge liniile, iar bucla interioară parcurge coloanele. Prelucrările de bază pe matrice sunt: suma elementelor, determinarea minimului și a maximului și numărarea elementelor cu o anumită proprietate. Pentru sumă, inițializăm o variabilă cu 0 și adunăm fiecare element: s = s + a[i][j]. Pentru maxim și minim, inițializăm variabila cu primul element a[1][1] și o actualizăm de fiecare dată când găsim un element mai mare, respectiv mai mic. Pentru numărare, folosim un contor inițializat cu 0, pe care îl creștem doar în interiorul condiției. Aceste prelucrări apar în aproape toate problemele de la BAC și stau la baza oricărei prelucrări ulterioare din modul.

Definiții esențiale

  • A parcurge o matrice înseamnă a vizita fiecare element exact o dată, folosind două bucle for imbricate: i pentru linii, j pentru coloane.
  • Suma elementelor: s = 0 înainte, apoi s = s + a[i][j] în interiorul parcurgerii.
  • Maximul (minimul) se inițializează cu primul element a[1][1], apoi se compară cu fiecare element.
  • Contorul numără elementele cu o proprietate: cnt = 0, apoi cnt++ când condiția este adevărată.

Algoritmul cheie - pseudocod

Algoritmul MaximMatrice(m, n): citește m, n și matricea a maxi <- a[1][1] pentru i = 1, m execută pentru j = 1, n execută dacă a[i][j] > maxi atunci maxi <- a[i][j] sfârșit dacă sfârșit pentru sfârșit pentru scrie maxi

Algoritmul cheie - cod C++

Maximul dintr-o matrice
maxi = a[1][1];
for (i = 1; i <= m; i++)
    for (j = 1; j <= n; j++)
        if (a[i][j] > maxi)
            maxi = a[i][j];

Greșeli comune de evitare

  • Inițializarea maximului cu 0: dacă matricea are valori negative, rezultatul este greșit. Folosește mereu a[1][1].
  • Contor incrementat în afara if-ului: numără atunci și elementele care nu respectă condiția.
  • Confundarea parcurgerii pe linii cu cea pe coloane: schimbarea ordinii buclelor schimbă complet rezultatul.

Exemplu practic

Profesorul vrea să afle câte note peste 7 au elevii clasei la o disciplină. Notele sunt organizate într-o matrice: fiecare linie este un elev, iar fiecare coloană este o probă. Programul numără notele care depășesc pragul, folosind un contor în interiorul parcurgerii.

Numărarea notelor peste 7
#include <iostream>
using namespace std;

int main() {
    int m, n, a[101][101], i, j, cnt = 0;
    cin >> m >> n;

    for (i = 1; i <= m; i++)
        for (j = 1; j <= n; j++)
            cin >> a[i][j];

    for (i = 1; i <= m; i++)
        for (j = 1; j <= n; j++)
            if (a[i][j] > 7)
                cnt++;

    cout << cnt;
    return 0;
}

Dacă în catalog apar 5 note peste 7, programul afișează 5 - exact răspunsul pe care profesorul îl caută în catalogul de note.

Sfaturi practice și trucuri

  • Pentru sume care pot depăși un miliard, declară long long.
  • Dacă trebuie și poziția maximului, adaugă variabilele lmax și cmax, actualizate împreună cu valoarea.
  • Scrie mai întâi citirea și o afișare de test a matricei; abia apoi adaugă prelucrarea.