Rotiri și transformări de matrici
În multe probleme trebuie să transformăm o matrice: să o rotim, să o oglindim sau să îi calculăm transpusa. Fiecare transformare urmează un tipar precis.
Transpusa
Transpusa unei matrici se obține
interschimbând liniile cu coloanele: elementul
a[i][j] devine a[j][i].
Original: Transpusa:
1 2 3 1 4 7
4 5 6 → 2 5 8
7 8 9 3 6 9
Cod (matrice pătratică, in-place)
for (int i = 1; i < n; i++)
for (int j = i + 1; j <= n; j++) {
int aux = a[i][j];
a[i][j] = a[j][i];
a[j][i] = aux;
}Parcurgem doar deasupra diagonalei
(j > i) și interschimbăm cu elementul
simetric.
Cod (matrice dreptunghiulară, cu matrice nouă)
int b[101][101];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
b[j][i] = a[i][j];
// b are m linii și n coloaneOglindire orizontală (sus-jos)
Interschimbăm linia 1 cu linia n, linia 2 cu linia n-1, etc.
Original: Oglindit:
1 2 3 7 8 9
4 5 6 → 4 5 6
7 8 9 1 2 3
for (int i = 1; i <= n / 2; i++)
for (int j = 1; j <= m; j++) {
int aux = a[i][j];
a[i][j] = a[n + 1 - i][j];
a[n + 1 - i][j] = aux;
}Oglindire verticală (stânga-dreapta)
Interschimbăm coloana 1 cu coloana m, coloana 2 cu coloana m-1, etc.
Original: Oglindit:
1 2 3 3 2 1
4 5 6 → 6 5 4
7 8 9 9 8 7
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m / 2; j++) {
int aux = a[i][j];
a[i][j] = a[i][m + 1 - j];
a[i][m + 1 - j] = aux;
}Rotire 90° în sensul acelor de ceas
Elementul a[i][j] ajunge pe poziția
b[j][n + 1 - i].
Original: Rotit 90° →
1 2 3 7 4 1
4 5 6 → 8 5 2
7 8 9 9 6 3
Formulă
b[j][n + 1 - i] = a[i][j]
Cod
int b[101][101];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
b[j][n + 1 - i] = a[i][j];Alternativ (fără matrice auxiliară, matrice pătratică)
Rotim cadru cu cadru, de la exterior spre interior. La fiecare cadru, rotim 4 elemente simultan:
for (int k = 1; k <= n / 2; k++)
for (int j = k; j < n + 1 - k; j++) {
int aux = a[k][j];
a[k][j] = a[n + 1 - j][k];
a[n + 1 - j][k] = a[n + 1 - k][n + 1 - j];
a[n + 1 - k][n + 1 - j] = a[j][n + 1 - k];
a[j][n + 1 - k] = aux;
}Cum funcționează rotirea în 4 pași?
Fiecare element se mută pe poziția următoare, în cerc:
a[k][j] → temp
a[n+1-j][k] → a[k][j]
a[n+1-k][n+1-j] → a[n+1-j][k]
a[j][n+1-k] → a[n+1-k][n+1-j]
temp → a[j][n+1-k]
Cele 4 elemente formează un “ciclu” pe cerc. Le rotim pe toate simultan cu o variabilă auxiliară.
Rotire 90° în sens trigonometric (anti-ceas)
b[n + 1 - j][i] = a[i][j]
Original: Rotit 90° ←
1 2 3 3 6 9
4 5 6 → 2 5 8
7 8 9 1 4 7
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
b[n + 1 - j][i] = a[i][j];Rotire 180°
b[n + 1 - i][m + 1 - j] = a[i][j]
Echivalent cu: oglindit orizontal + oglindit vertical (sau invers).
Original: Rotit 180°:
1 2 3 9 8 7
4 5 6 → 6 5 4
7 8 9 3 2 1
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
b[n + 1 - i][m + 1 - j] = a[i][j];Tabel rezumativ formule
| Transformare | Formula: b[?][?] = a[i][j] |
|---|---|
| Transpusa | b[j][i] = a[i][j] |
| Oglindire orizontală | b[n+1-i][j] = a[i][j] |
| Oglindire verticală | b[i][m+1-j] = a[i][j] |
| Rotire 90° ceas | b[j][n+1-i] = a[i][j] |
| Rotire 90° anti-ceas | b[n+1-j][i] = a[i][j] |
| Rotire 180° | b[n+1-i][m+1-j] = a[i][j] |
Relații utile: - Rotire 90° ceas = transpusă + oglindire verticală - Rotire 90° anti-ceas = transpusă + oglindire orizontală - Rotire 180° = oglindire orizontală + oglindire verticală
Exemplu complet: toate transformările
#include <fstream>
using namespace std;
ifstream fin("date.in");
ofstream fout("date.out");
int a[101][101], b[101][101];
int n;
void afiseaza(int mat[][101], int lin, int col) {
for (int i = 1; i <= lin; i++) {
for (int j = 1; j <= col; j++)
fout << mat[i][j] << " ";
fout << "\n";
}
fout << "\n";
}
int main()
{
fin >> n;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
fin >> a[i][j];
// Rotire 90° ceas
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
b[j][n + 1 - i] = a[i][j];
fout << "Rotire 90 ceas:" << "\n";
afiseaza(b, n, n);
// Transpusa
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
b[j][i] = a[i][j];
fout << "Transpusa:" << "\n";
afiseaza(b, n, n);
return 0;
}Greșeli frecvente
1. Rotire in-place fără auxiliar
a[i][j] = a[j][i]; // am pierdut valoarea veche a lui a[i][j]!Folosește matrice auxiliară b sau interschimbare
cu aux.
2. Formula greșită la rotire
Cele mai confundate: 90° ceas vs anti-ceas. Testează mereu pe o matrice mică (2x2 sau 3x3).
3. Rotire pe matrice dreptunghiulară
Rotirea 90° a unei matrici n x m produce o
matrice m x n. Dimensiunile se schimbă.
4. Oglindire pe jumătate
La oglindire, parcurgem doar jumătate din matrice (n/2 linii sau m/2 coloane). Altfel, interschimbăm de două ori și revenim la original.
Ce să reții
- Transpusa: interschimbăm
a[i][j]cua[j][i]. - Oglindire: interschimbăm linii (orizontală) sau coloane (verticală).
- Rotire 90°: folosim formula
b[j][n+1-i] = a[i][j](ceas) saub[n+1-j][i] = a[i][j](anti-ceas). - Rotire 180°:
b[n+1-i][m+1-j] = a[i][j]. - Folosește matrice auxiliară sau interschimbare cu
aux. - Rotirea schimbă dimensiunile pe matrici dreptunghiulare.