Ce vei învăța astăzi?
După această lecție vei ști să prelucrezi diagonala principală a unei matrice pătrate, elementele deasupra diagonalei și vei putea localiza poziția maximului.
Diagonala principală a unei matrice
Definiție: Diagonala principală a unei matrice pătrate este formată din elementele pentru care i == j, adică a[1][1], a[2][2], ..., a[n][n]. Diagonala secundară este formată din elementele cu i + j == n + 1.
Exemplu: suma elementelor de pe diagonala principală
#include <iostream>
using namespace std;
int main() {
int n, a[101][101], i, j, sp = 0;
cin >> n;
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
cin >> a[i][j];
for (i = 1; i <= n; i++)
sp = sp + a[i][i];
cout << sp;
return 0;
}
Observă: pe diagonala principală parcurgem doar cu un singur indice i, accesând a[i][i].
Elementele deasupra diagonalei principale
Elementele deasupra diagonalei principale îndeplinesc condiția i < j (linia este mai mică decât coloana). Elementele sub diagonală îndeplinesc condiția i > j.
#include <iostream>
using namespace std;
int main() {
int n, a[101][101], i, j, s = 0;
cin >> n;
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
cin >> a[i][j];
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
if (i < j)
s = s + a[i][j];
cout << s;
return 0;
}
Observă: verificăm condiția i < j în interiorul parcurgerii cu două bucle. Pentru zona de sub diagonală folosim i > j.
Poziția maximului din matrice
Pe lângă valoarea maximă, putem memora și poziția (linia și coloana) la care apare. Dacă folosim condiția strictă >, rămâne prima apariție (prima poziție în care apare valoarea maximă).
#include <iostream>
using namespace std;
int main() {
int n, a[101][101], i, j, maxi, lmax = 1, cmax = 1;
cin >> n;
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
cin >> a[i][j];
maxi = a[1][1];
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
if (a[i][j] > maxi) {
maxi = a[i][j];
lmax = i;
cmax = j;
}
cout << maxi << " " << lmax << " " << cmax;
return 0;
}
Observă: lmax și cmax se actualizează doar împreună cu maxi, exact când găsim un element mai mare.
Exercițiu de completare
Completează enunțul cu cuvintele potrivite:
Elementele de pe diagonala principală îndeplinesc condiția ______. Elementele deasupra diagonalei principale îndeplinesc condiția ______, iar cele de sub diagonală, condiția ______.
Bancă de cuvinte:
Exercițiu de completare 2
Completează afirmațiile despre diagonale și maxim:
Suma diagonalei principale se calculează adunând elementele ______. Diagonala secundară are elementele cu ______. Poziția maximului se memorează cu variabilele ______ și cmax.
Bancă de cuvinte:
Test de înțelegere
Test rapid - matrice pătrată:
1. Elementele de pe diagonala secundară îndeplinesc condiția:
2. Elementele deasupra diagonalei principale îndeplinesc condiția:
3. Dacă folosim condiția strictă a[i][j] > maxi, maximul reținut este:
i + j == n în loc de i + j == n + 1. Cu indexarea de la 1, suma indicilor oricărui element de pe diagonala secundară este întotdeauna n + 1.Aprofundare
De ce elementele cu i < j sunt deasupra diagonalei principale? Imaginează-ți o sală de clasă văzută din lateral: fiecare elev are coordonatele (linie, coloană). Elevii „deasupra" diagonalei sunt aceia pentru care numărul coloanei depășește numărul liniei. Exact cum funcționează și în matematică, unde triunghiul superior este format din pozițiile cu i < j. Simetria acestor zone este importantă: numărul de elemente deasupra diagonalei este egal cu numărul de elemente de sub ea, adică n * (n - 1) / 2.
Diagonala secundară și capcana ei: elementele diagonalei secundare îndeplinesc condiția i + j == n + 1. Atenție: pentru o matrice cu n pe latură, suma maximă a indicilor este n + n, deci condiția se scrie i + j == n + 1, nu i + j == n. O greșeală foarte des întâlnită la simulări. Când matricea are dimensiuni diferite (m și n), diagonalele nu mai sunt bine definite și se tratează doar „coloana = linie" pentru cazuri particulare.
Parcurgerea doar a zonei cerute (optimizare): pentru suma deasupra diagonalei putem evita verificarea condiției, parcurgând direct j de la i + 1 la n în bucla interioară. Astfel vizităm numai elementele de care avem nevoie, iar codul devine mai rapid și mai clar:
for (i = 1; i <= n; i++)
for (j = i + 1; j <= n; j++)
s = s + a[i][j];
Poziția maximului - capcana cu semne: pentru matrice cu valori negative, maximul trebuie inițializat cu a[1][1], nu cu 0. Iar dacă problema cere „linia și coloana pe care apare maximul", amintesc că folosirea lui > păstrează prima apariție, iar a lui >= ultima apariție - detalii care fac diferența între 5 și 10 la BAC.
PbInfo - Suma diagonalelor
Enunț:
Cerință: Se citește o matrice pătrată cu n linii și n coloane. Să se afișeze suma elementelor de pe diagonala principală și suma elementelor de pe diagonala secundară, separate printr-un spațiu.
Date de intrare:
Programul citește de la tastatură numărul n, apoi elementele matricei, linie cu linie.
Date de ieșire:
Programul va afișa suma diagonalelor principală și secundară, separate printr-un spațiu. Dacă n este impar, elementul din centru se adună o singură dată.
Restricții și precizări:
1 <= n <= 100, elementele matricei sunt numere întregi.
Exemplu:
Intrare:
3 1 2 3 4 5 6 7 8 9
Ieșire:
15 15
Cum gândim soluția:
- Sumăm diagonala principală cu
sp = sp + a[i][i] - Sumăm diagonala secundară cu
ss = ss + a[i][n - i + 1] - Dacă
neste impar, scădem elementul central din suma secundară, deoarece a fost adunat de două ori - Afișăm cele două sume
Scrie soluția în C++:
Soluție corectă:
#include <iostream>
using namespace std;
int main() {
int n, a[101][101], i, j, sp = 0, ss = 0;
cin >> n;
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
cin >> a[i][j];
for (i = 1; i <= n; i++) {
sp = sp + a[i][i];
ss = ss + a[i][n - i + 1];
}
if (n % 2 == 1)
ss = ss - a[n / 2 + 1][n / 2 + 1];
cout << sp << " " << ss;
return 0;
}
Ce învățăm: cele două diagonale se parcurg cu un singur indice; elementul central, la n impar, apare pe ambele diagonale și trebuie numărat o singură dată.
PbInfo - Elemente deasupra diagonalei principale
Enunț:
Cerință: Se citește o matrice pătrată cu n linii și n coloane. Să se afișeze numărul elementelor situate deasupra diagonalei principale și suma acestora, separate printr-un spațiu.
Date de intrare:
Programul citește de la tastatură numărul n, apoi elementele matricei, linie cu linie.
Date de ieșire:
Programul va afișa numărul elementelor cu i < j și suma lor, separate printr-un spațiu.
Restricții și precizări:
1 <= n <= 100, elementele matricei sunt numere întregi.
Exemplu:
Intrare:
3 1 2 3 4 5 6 7 8 9
Ieșire:
3 11
Cum gândim soluția:
- Parcurgem matricea cu două bucle
for - Verificăm condiția
i < jpentru fiecare element - Numărăm elementele cu un contor și le adunăm la o sumă
- Afișăm contorul și suma
Scrie soluția în C++:
Soluție corectă:
#include <iostream>
using namespace std;
int main() {
int n, a[101][101], i, j, s = 0, cnt = 0;
cin >> n;
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
cin >> a[i][j];
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
if (i < j) {
cnt++;
s = s + a[i][j];
}
cout << cnt << " " << s;
return 0;
}
Ce învățăm: o singură parcurgere a matricei este suficientă pentru a număra și a suma elementele din zona de deasupra diagonalei principale.
Exercițiul Practic: Matricea aplicativă
Sarcini de lucru
Completează următoarele sarcini pentru a-ți consolida prelucrarea diagonalelor
Sarcina 1: Suma elementelor de sub diagonala principală
Cerință: Scrie un program C++ care citește o matrice pătrată cu n linii și coloane și afișează suma elementelor situate sub diagonala principală (condiția i > j).
Soluție pentru Sarcina 1:
#include <iostream>
using namespace std;
int main() {
int n, a[101][101], i, j, s = 0;
cin >> n;
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
cin >> a[i][j];
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
if (i > j)
s = s + a[i][j];
cout << s;
return 0;
}
Verifică: zona de sub diagonala principală corespunde condiției i > j.
Sarcina 2: Suma diagonalei secundare
Cerință: Scrie un program C++ care citește o matrice pătrată cu n linii și coloane și afișează suma elementelor de pe diagonala secundară.
Soluție pentru Sarcina 2:
#include <iostream>
using namespace std;
int main() {
int n, a[101][101], i, j, ss = 0;
cin >> n;
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
cin >> a[i][j];
for (i = 1; i <= n; i++)
ss = ss + a[i][n - i + 1];
cout << ss;
return 0;
}
Verifică: elementul de pe diagonala secundară din linia i are coloana n - i + 1.
Scrie pe caiet - De reținut
Titlul lecției
Ora 3: Matricea - probleme aplicative
Definiția lecției
Diagonala principală a unei matrice pătrate este formată din elementele cu i == j, adică a[1][1], a[2][2], ..., a[n][n], iar diagonala secundară din elementele cu i + j == n + 1. Elementele deasupra diagonalei principale îndeplinesc condiția i < j, iar cele de sub diagonală, condiția i > j. Diagonalele se parcurg cu un singur indice, a[i][i], respectiv a[i][n + 1 - i], fără a avea nevoie de două bucle. Pe lângă diagonale, lecția prezintă localizarea poziției maximului: memorăm linia lmax și coloana cmax împreună cu valoarea maximă, actualizându-le doar când găsim un element mai mare. Folosind condiția strictă >, păstrăm prima apariție a maximului; folosind >=, păstrăm ultima apariție. Aceste noțiuni sunt punctate frecvent la BAC, atât la teorie, cât și la probleme.
Definiții esențiale
- Diagonala principală: elementele cu
i == j, adicăa[1][1],a[2][2], ...,a[n][n]. - Diagonala secundară: elementele cu
i + j == n + 1. - Deasupra diagonalei principale:
i < j; sub diagonală:i > j. - Poziția maximului: variabilele
lmaxșicmax, actualizate împreună cu valoarea maximă.
Algoritmul cheie - pseudocod
Algoritmul cheie - cod C++
s = 0;
for (i = 1; i <= n; i++)
for (j = i + 1; j <= n; j++)
s = s + a[i][j];
Greșeli comune de evitare
- Condiția greșită a diagonalei secundare: este
i + j == n + 1, nui + j == n. - Inițializarea maximului cu 0 pentru o matrice cu valori negative - rezultat greșit.
- Parcurgerea întregii matrice cu if în loc de interval direct: funcționează, dar este mai lent și mai ușor de greșit.
Exemplu practic
Într-o competiție sportivă, fiecare dintre cei n arbitri notează fiecare sportiv, iar rezultatele formează o matrice pătrată. Organizatorii vor să afle suma notelor de pe diagonala principală, adică notele pe care arbitrul le-a dat sportivului cu același număr de ordine. Programul de mai jos calculează această sumă parcurgând doar elementele a[i][i].
#include <iostream>
using namespace std;
int main() {
int n, a[101][101], i, j, sp = 0;
cin >> n;
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
cin >> a[i][j];
for (i = 1; i <= n; i++)
sp = sp + a[i][i];
cout << sp;
return 0;
}
Pentru o matrice 3 x 3, programul adună doar a[1][1], a[2][2] și a[3][3] - cele trei note de pe diagonala principală.
Sfaturi practice și trucuri
- Pentru zona de deasupra diagonalei parcurge direct
jde lai + 1lan- fără if. - Numărul de elemente deasupra diagonalei este
n * (n - 1) / 2- folosește-l la verificări. - Dacă problema cere ambele diagonale, verifică dacă elementul din mijloc (pentru n impar) nu se numără de două ori.