O matrice (tablou bidimensional) e un tabel de valori organizat pe linii și coloane. La BAC informatică, matricele apar la itemii scurți de la Subiectul II și la problema cu tablouri de la Subiectul III: construiești o matrice după o regulă, calculezi sume pe linii sau coloane, cauți elemente cu o proprietate. Toate pornesc de la aceleași câteva tipare de parcurgere în C++, pe care le vezi mai jos.
Declararea și indicii
int a[101][101]; // linii 0..100, coloane 0..100
int n, m; // n linii, m coloane folosite efectiv
Elementul de pe linia i și coloana j se scrie a[i][j] — întâi linia, apoi coloana. Ca la vectori, dimensiunea declarată e cea maximă, iar n și m spun cât folosești efectiv. Numerotarea poate începe de la 0 sau de la 1; aici folosim 1, ca în multe enunțuri. Declarată global, matricea e inițializată cu 0.
Atenție la memorie: o matrice int de 1000 × 1000 ocupă aproximativ 4 MB. Declar-o global, nu în main, unde spațiul pentru variabile locale e mult mai mic.
Citirea și afișarea
#include <iostream>
using namespace std;
int a[101][101], n, m;
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
cout << a[i][j] << " ";
cout << endl; // linie nouă după fiecare linie a matricei
}
return 0;
}
Citirea se face pe linii: bucla exterioară e pe i (linii), cea interioară pe j (coloane), pentru că așa sunt date valorile în fișier sau la tastatură. La afișare, endl (sau '\n') stă după bucla interioară, nu în ea. Pus în interior, fiecare element ar apărea pe un rând separat; uitat de tot, matricea iese pe un singur rând.
Parcurgerea pe linii și pe coloane
Pentru exemplele de mai jos folosim matricea cu n = 3 linii și m = 4 coloane:
1 2 3 4
5 6 7 8
9 10 11 12
Suma fiecărei linii: pentru fiecare linie i, pornești suma de la 0 și aduni elementele de pe coloanele 1..m.
for (int i = 1; i <= n; i++)
{
int s = 0; // resetată pentru fiecare linie
for (int j = 1; j <= m; j++)
s = s + a[i][j];
cout << s << " "; // 10 26 42
}
Suma fiecărei coloane: inversezi buclele — exterior pe coloane, interior pe linii.
for (int j = 1; j <= m; j++)
{
int s = 0;
for (int i = 1; i <= n; i++)
s = s + a[i][j];
cout << s << " "; // 15 18 21 24
}
Verificare rapidă: suma sumelor pe linii (10 + 26 + 42) și suma sumelor pe coloane (15 + 18 + 21 + 24) trebuie să dea același total, 78. E un test bun pe ciornă.
Maximul pe fiecare linie și linia cu suma maximă
int smax = -1, lmax = 0;
for (int i = 1; i <= n; i++)
{
int mx = a[i][1], s = 0;
for (int j = 1; j <= m; j++)
{
if (a[i][j] > mx) mx = a[i][j];
s = s + a[i][j];
}
cout << "maximul liniei " << i << ": " << mx << endl;
if (s > smax) { smax = s; lmax = i; }
}
cout << "linia cu suma maxima: " << lmax;
Pe exemplu: maximele pe linii sunt 4, 8, 12, iar linia cu suma maximă e 3 (suma 42). Inițializarea smax = -1 merge doar dacă elementele sunt naturale; altfel pornește smax de la suma primei linii.
Căutarea unui element
Ca să afli dacă valoarea x apare în matrice și unde apare prima dată (parcurgând pe linii), folosești o variabilă de tip „găsit”:
bool gasit = false;
for (int i = 1; i <= n && !gasit; i++)
for (int j = 1; j <= m && !gasit; j++)
if (a[i][j] == x)
{
cout << i << " " << j;
gasit = true;
}
if (!gasit) cout << "nu exista";
Condiția !gasit din ambele bucle oprește parcurgerea imediat după prima apariție. Un simplu break ar ieși doar din bucla interioară, iar cea exterioară ar continua cu linia următoare.
Interschimbarea a două linii sau coloane
// liniile p și q
for (int j = 1; j <= m; j++)
{ int aux = a[p][j]; a[p][j] = a[q][j]; a[q][j] = aux; }
// coloanele p și q
for (int i = 1; i <= n; i++)
{ int aux = a[i][p]; a[i][p] = a[i][q]; a[i][q] = aux; }
Reține simetria: la linii, indicele care variază e coloana j; la coloane, variază linia i.
Program complet
Se citesc n, m și o matrice cu n linii și m coloane de numere naturale. Afișați indicii coloanelor care conțin doar numere pare, sau mesajul „nu exista”.
#include <iostream>
using namespace std;
int a[101][101], n, m;
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
bool exista = false;
for (int j = 1; j <= m; j++)
{
bool toatePare = true;
for (int i = 1; i <= n; i++)
if (a[i][j] % 2 != 0) toatePare = false;
if (toatePare)
{
cout << j << " ";
exista = true;
}
}
if (!exista) cout << "nu exista";
return 0;
}
Pentru matricea cu liniile 2 3 4 și 6 8 10, coloana 1 (2, 6) și coloana 3 (4, 10) au doar numere pare, iar coloana 2 conține 3, deci programul afișează 1 3.
De reținut
- ●
a[i][j]: întâi linia, apoi coloana. - ● Citirea și afișarea se fac pe linii;
endlvine după bucla pe coloane. - ● Pentru prelucrări pe coloane, bucla exterioară e pe j, cea interioară pe i.
- ● Sumele, maximele și indicatorii „pentru fiecare linie/coloană” se reinițializează în bucla exterioară.
- ● Pentru oprirea ambelor bucle folosește o variabilă
gasit, nu doarbreak. - ● Matricele mari se declară global.