1. Zone speciale intr-o matrice patratica
j=0 j=1 j=2 j=3 j=4 i=0 [ 1 2 3 4 5 ] i=1 [ 6 7 8 9 10 ] i=2 [ 11 12 13 14 15 ] i=3 [ 16 17 18 19 20 ] i=4 [ 21 22 23 24 25 ] Diagonala principala: 1, 7, 13, 19, 25 (i creste odata cu j) Diagonala secundara : 5, 9, 13, 17, 21 (cand i creste, j scade)
Diagonala principala .... i == j Diagonala secundara ..... i + j == n - 1 Triunghi deasupra dp .... i < j Triunghi dedesubt dp .... i > j Zona N (sus) .... i < j si i + j < n - 1 Zona S (jos) .... i > j si i + j > n - 1 Zona V (stanga) .. i > j si i + j < n - 1 Zona E (dreapta) . i < j si i + j > n - 1
Fiecare zona este intersectia a doua conditii: una data de diagonala principala, cealalta de diagonala secundara. Elementele de pe diagonale nu apartin niciunei zone.
#include <iostream>
using namespace std;
int main() {
int n = 5, a[5][5];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
a[i][j] = i * n + j + 1;
int dp = 0, ds = 0, sus = 0, jos = 0;
int nord = 0, sud = 0, vest = 0, est = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
if (i == j) dp += a[i][j];
if (i + j == n - 1) ds += a[i][j];
if (i < j) sus += a[i][j];
if (i > j) jos += a[i][j];
if (i < j && i + j < n - 1) nord += a[i][j];
if (i > j && i + j > n - 1) sud += a[i][j];
if (i > j && i + j < n - 1) vest += a[i][j];
if (i < j && i + j > n - 1) est += a[i][j];
}
cout << "diagonala principala = " << dp << endl;
cout << "diagonala secundara = " << ds << endl;
cout << "triunghi de sus = " << sus << endl;
cout << "triunghi de jos = " << jos << endl;
cout << "zona N = " << nord << ", S = " << sud
<< ", V = " << vest << ", E = " << est << endl;
return 0;
}diagonala principala = 65 diagonala secundara = 65 triunghi de sus = 90 triunghi de jos = 170 zona N = 17, S = 87, V = 45, E = 59
2. Inmultirea a doua matrice
A (2 x 3) B (3 x 2)
[ 1 2 3 ] [ 7 8 ]
[ 4 5 6 ] [ 9 10 ]
[ 11 12 ]
Elementul C[0][0]: linia 0 din A cu coloana 0 din B
1*7 + 2*9 + 3*11 = 7 + 18 + 33 = 58
Elementul C[1][1]: linia 1 din A cu coloana 1 din B
4*8 + 5*10 + 6*12 = 32 + 50 + 72 = 154C[i][j] = suma dupa k, de la 0 la n-1, a produselor A[i][k] * B[k][j].
Cu alte cuvinte: fiecare element al rezultatului este produsul scalar dintre o linie din A si o coloana din B. Dimensiunile se citesc usor asa: (m x n) * (n x p) = m x p — dimensiunile din mijloc trebuie sa coincida si dispar.
#include <iostream>
using namespace std;
int main() {
int m = 2, n = 3, p = 2;
int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
int b[3][2] = {{7, 8}, {9, 10}, {11, 12}};
int c[2][2];
for (int i = 0; i < m; i++)
for (int j = 0; j < p; j++) {
c[i][j] = 0; // ZERO inainte de a aduna
for (int k = 0; k < n; k++)
c[i][j] += a[i][k] * b[k][j];
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < p; j++) cout << c[i][j] << " ";
cout << endl;
}
return 0;
}58 64 139 154
Uitarea liniei c[i][j] = 0; Fara ea, c[i][j] contine gunoi din memorie si toate sumele ies aiurea. Alternativa sigura: foloseste o variabila locala int s = 0; aduni in s, apoi c[i][j] = s; la finalul buclei dupa k.
3. Matricea unitate, necomutativitatea si puterea Ak
A = [ 1 2 ] B = [ 1 0 ]
[ 0 1 ] [ 3 1 ]
A * B = [ 7 2 ] B * A = [ 1 2 ]
[ 3 1 ] [ 3 7 ]
Aceleasi matrice, rezultate diferite.rezultat = 1; inainte de o ridicare la putere obisnuita.#include <iostream>
using namespace std;
const int N = 2;
void inmulteste(int A[N][N], int B[N][N], int C[N][N]) {
int T[N][N]; // matrice temporara: A sau B pot fi
for (int i = 0; i < N; i++) // chiar C, si le-am strica pe parcurs
for (int j = 0; j < N; j++) {
T[i][j] = 0;
for (int k = 0; k < N; k++) T[i][j] += A[i][k] * B[k][j];
}
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++) C[i][j] = T[i][j];
}
int main() {
int F[N][N] = {{1, 1}, {1, 0}};
int P[N][N] = {{1, 0}, {0, 1}}; // matricea unitate I2
for (int pas = 1; pas <= 5; pas++) {
inmulteste(P, F, P);
cout << "F^" << pas << " = [" << P[0][0] << " " << P[0][1]
<< " ; " << P[1][0] << " " << P[1][1] << "]" << endl;
}
return 0;
}F^1 = [1 1 ; 1 0] F^2 = [2 1 ; 1 1] F^3 = [3 2 ; 2 1] F^4 = [5 3 ; 3 2] F^5 = [8 5 ; 5 3]
Uita-te la numerele care apar: 1, 1, 2, 3, 5, 8 — sirul lui Fibonacci. Nu e o coincidenta amuzanta, ci proprietatea acestei matrice: in coltul stanga-sus al lui Fk sta termenul Fibonacci de rang k+1 (cu conventia F(1) = F(2) = 1). Verifica pe output: F5 are in coltul stanga-sus 8, care este chiar al saselea termen din 1, 1, 2, 3, 5, 8.
4. Parcurgerea in spirala
1 2 3 4
5 6 7 8
9 10 11 12
Tur 1: 1 2 3 4 (randul de sus, stanga -> dreapta)
8 12 (coloana din dreapta, in jos)
11 10 9 (randul de jos, dreapta -> stanga)
5 (coloana din stanga, in sus)
Tur 2: 6 7 (ce a mai ramas in interior)
Rezultat: 1 2 3 4 8 12 11 10 9 5 6 7sus, jos, st (stanga) si dr (dreapta). Fiecare tur consuma cate o margine si o strange spre interior. Bucla merge cat timp sus <= jos si st <= dr, adica atat timp cat mai exista dreptunghi neparcurs.#include <iostream>
using namespace std;
int main() {
int m = 3, n = 4, a[3][4];
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
a[i][j] = i * n + j + 1;
int sus = 0, jos = m - 1, st = 0, dr = n - 1;
while (sus <= jos && st <= dr) {
for (int j = st; j <= dr; j++) cout << a[sus][j] << " ";
sus++;
for (int i = sus; i <= jos; i++) cout << a[i][dr] << " ";
dr--;
if (sus <= jos) { // mai exista rand de jos?
for (int j = dr; j >= st; j--) cout << a[jos][j] << " ";
jos--;
}
if (st <= dr) { // mai exista coloana stanga?
for (int i = jos; i >= sus; i--) cout << a[i][st] << " ";
st++;
}
}
cout << endl;
return 0;
}1 2 3 4 8 12 11 10 9 5 6 7
1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10
5. Bordarea unei matrice
Initiala (2 x 3) Bordata (4 x 5)
1 2 3 0 0 0 0 0
4 5 6 0 1 2 3 0
0 4 5 6 0
0 0 0 0 0
Elementul care era pe pozitia (0,0) este acum pe (1,1):
fiecare indice a crescut cu 1.(i, j) ajunge la (i+1, j+1).Bordarea apare la Bacalaureat in doua feluri. Ca cerinta in sine („bordati matricea cu un chenar avand o valoare data si afisati matricea obtinuta”) si, mult mai des, ca truc de implementare: daca lucrezi cu vecinii unui element, un chenar de zerouri scapa de toate verificarile de tipul if (i > 0 && j < n - 1 && ...), unde se pierd de obicei punctele.
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
int m = 2, n = 3;
int b[10][10] = {0}; // totul 0, deci chenarul e deja pus
int v[2][3] = {{1, 2, 3}, {4, 5, 6}};
for (int i = 1; i <= m; i++) // datele intra de la (1,1)
for (int j = 1; j <= n; j++)
b[i][j] = v[i - 1][j - 1];
cout << "Matricea bordata (" << m + 2 << " x " << n + 2 << "):" << endl;
for (int i = 0; i <= m + 1; i++) {
for (int j = 0; j <= n + 1; j++) cout << setw(2) << b[i][j] << " ";
cout << endl;
}
cout << "Suma celor 8 vecini (fara verificari de margine):" << endl;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
int s = 0;
for (int di = -1; di <= 1; di++)
for (int dj = -1; dj <= 1; dj++)
if (di || dj) s += b[i + di][j + dj]; // sare peste el insusi
cout << setw(3) << s;
}
cout << endl;
}
return 0;
}Matricea bordata (4 x 5): 0 0 0 0 0 0 1 2 3 0 0 4 5 6 0 0 0 0 0 0 Suma celor 8 vecini (fara verificari de margine): 11 19 13 8 16 10
if ramas in bucla este if (di || dj), care sare peste elementul insusi; verificarile de margine au disparut complet.Daca matricea initiala are cel mult 100 x 100, declara b[102][102], nu b[100][100]: chenarul cere doua linii si doua coloane in plus. Rezervarea unei margini in plus e mai ieftina decat o depasire de indice la corectare.
6. Recapitulare operationala si capcanele de la Bac
Operatie Complexitate -------------------------------- ------------- Parcurgere completa (m x n) O(m * n) Sume pe zone / diagonale O(n^2) Doar diagonala (o singura bucla) O(n) Inmultire A(m x n) * B(n x p) O(m * n * p) Inmultire matrice patratice O(n^3) Putere A^k prin inmultiri O(k * n^3) Parcurgere in spirala O(m * n) Bordare O(m * n)
1. Indici de la 0 sau de la 1? Diagonala secundara e i + j == n - 1 cu indici de la 0, dar i + j == n + 1 cu indici de la 1. Scrie pe ciorna un exemplu mic si verifica. 2. c[i][j] = 0 uitat inainte de suma la inmultire. 3. Conditia de compatibilitate neverificata: A(2x3) * B(2x3) nu se poate calcula. 4. Spirala fara cele doua if-uri din mijloc: duplica randul (sau coloana) din ultimul tur la matricele dreptunghiulare, de exemplu 3 x 4. Pe matrice patratice iese corect si fara ele, deci testul facut doar pe 4 x 4 nu prinde nimic. 5. Bordare fara loc rezervat in declarare: b[100][100] nu incape o matrice bordata 102x102. 6. Zonele N, S, V, E: fiecare cere DOUA conditii, una pe fiecare diagonala. Cu una singura obtii triunghiul, nu zona.