Verificarea unei matrice simetrice în C++
Compară celulele oglindite față de diagonala principală. Verifică o singură dată fiecare pereche și diferențiază simetria de egalitatea diagonalelor.
În acest material
O matrice pătratică este simetrică față de diagonala principală dacă a[i][j]=a[j][i] pentru orice pereche de indici. Celula de pe linia i, coloana j se compară cu cea de pe linia j, coloana i. Nu comparăm doar cele două diagonale.
Desenează perechile oglindite
Pentru liniile 1 2 3, 2 4 5, 3 5 6, perechile din afara diagonalei sunt 2 cu 2, 3 cu 3 și 5 cu 5. Toate coincid, deci matricea este simetrică. Dacă schimbăm doar ultima valoare 5 de pe linia a treia în 7, perechea (1,2) și (2,1) nu mai coincide și răspunsul devine NU.
Citim 1≤n≤100 și n² întregi. Afișăm DA sau NU. Indicii sunt de la zero, iar tabloul clasic rezervă 100×100 celule. Folosim numai pătratul n×n. O matrice dreptunghiulară nu intră în definiția verificată aici.
Comparăm numai deasupra diagonalei
Celulele diagonalei au i=j și sunt egale cu ele însele. În afara diagonalei, verificarea ambelor perechi (i,j) și (j,i) ar repeta aceeași comparație. Alegem j>i și verificăm fiecare pereche o dată.
Indicatorul simetrica pornește adevărat. O singură nepotrivire îl transformă în fals. Nu îl setăm din nou la adevărat pentru o pereche ulterioară egală: proprietatea cere ca toate perechile să coincidă.
Matricea 1,2,3 / 2,4,5 / 3,5,6 este simetrică: fiecare element a[i][j] este egal cu a[j][i].Mărește schema ↗
Varianta cu tablou clasic
#include <iostream>
using namespace std;
int main() {
int n; cin >> n; int a[100][100];
for(int i=0;i<n;++i) for(int j=0;j<n;++j) cin >> a[i][j];
bool simetrica=true;
for(int i=0;i<n;++i) for(int j=i+1;j<n;++j)
if(a[i][j]!=a[j][i]) simetrica=false;
cout << (simetrica?"DA\n":"NU\n");
}
Varianta echivalentă cu std::vector
Păstrăm limitele intrării și aceleași rezultate. Tabloul clasic rezervă capacitatea maximă; vectorul construiește numărul de elemente necesare. Indicii folosiți de algoritm rămân aceiași.
#include <vector>
#include <iostream>
using namespace std;
int main() {
int n; cin >> n; vector<vector<int>> a(n,vector<int>(n));
for(int i=0;i<n;++i) for(int j=0;j<n;++j) cin >> a[i][j];
bool simetrica=true;
for(int i=0;i<n;++i) for(int j=i+1;j<n;++j)
if(a[i][j]!=a[j][i]) simetrica=false;
cout << (simetrica?"DA\n":"NU\n");
}
Numărul comparațiilor
Prima linie verifică n-1 perechi, următoarea n-2, până la ultima care nu mai verifică nimic. În total sunt n(n-1)/2 comparații. Ordinul de creștere rămâne O(n²), chiar dacă am eliminat aproximativ jumătate dintre verificările unei parcurgeri complete.
Citirea ocupă tot O(n²) timp, iar stocarea matricei O(n²) elemente. În afara datelor folosim memorie constantă. Pentru n=1 nu există perechi diferite, iar răspunsul este DA, indiferent de valoarea singurei celule.
Exersează
Testează o matrice 2×2 cu liniile 1 4 și 4 9, apoi schimbă numai valoarea din stânga jos. Prima este simetrică, a doua nu. Construiește și un exemplu cu diagonale având aceeași sumă, dar cu a[0][1] diferit de a[1][0]: egalitatea sumelor nu este suficientă.
Continuă cu transpunerea, diagonalele și condițiile logice.
Întrebări frecvente
Ce înseamnă o matrice simetrică față de diagonala principală?
O matrice pătratică în care a[i][j] == a[j][i] pentru orice pereche de indici. Egalitatea numai a elementelor de pe diagonale nu este suficientă.
Trebuie să compar fiecare pereche de două ori?
Nu. Este suficient să verifici celulele de pe o singură parte a diagonalei principale, de exemplu i<j, cu perechile lor oglindite. Celulele diagonalei se compară cu ele însele.
Este o matrice de 1 pe 1 simetrică?
Da. Singura celulă coincide cu propria transpusă. Acest caz verifică dacă algoritmul acceptă corect absența perechilor din afara diagonalei.
Un pas mai departe
Autentifică-te pentru a păstra progresul în cont.