Vectori și matrice

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.

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].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.

Exersează cu o problemă →