Lecție pentru bacalaureat · Informatică

Tablouri bidimensionale (matrice)

Clasa a X-a

Ideile de bază pe scurt și, unde există, exercițiile din subiectele de BAC care le verifică. Lecția completă, animată, cu grile și exerciții corectate, e în aplicația Tomomi.

Pe scurt

Formulă

Sintaxă: declararea și citirea unei matrice

Forma canonică: capacitățile maxime se declară o dată, apoi primele n linii și m coloane se umplu din intrare, cu două bucle imbricate:

int a[10][10];
int n;
int m;
cin >> n >> m;
for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
        cin >> a[i][j];
    }
}
Sfat

Capcana: întâi linia, apoi coloana

a[i][j] este LINIA i, COLOANA j - nu coordonatele (x, y) de la matematică. a[1][3] și a[3][1] sunt celule diferite. Și indicii pornesc de la 0 pe ambele dimensiuni: ultima celulă este a[n - 1][m - 1], nu a[n][m].

Formulă

Șablon: suma pe fiecare linie

Acumulatorul se resetează la începutul fiecărei linii:

for (int i = 0; i < n; i++) {
    int s = 0;
    for (int j = 0; j < m; j++) {
        s = s + a[i][j];
    }
    cout << s << "\n";
}
// coloana fixă j: bucla pe i, s = s + a[i][j];
Idee

Idee: un indice fix, unul liber

Suma pe o linie ține i fix și lasă j să alerge; suma pe o coloană ține j fix și lasă i să alerge. Orice prelucrare pe zone (linii, coloane, diagonale) pornește de la întrebarea: care indice este fix și care variază?

Formulă

Șablon: diagonalele matricei pătratice

Câte o singură buclă pe i ajunge pentru fiecare diagonală:

// principala: i == j
s = s + a[i][i];
// secundara: i + j == n - 1
s = s + a[i][n - 1 - i];
Sfat

Capcana: transpusa se face o singură dată per pereche

La transpunere interschimbi a[i][j] cu a[j][i]. Dacă bucla interioară pornește de la j = 0, fiecare pereche se schimbă de două ori și revine la loc. Pornește de la j = i + 1: vizitezi doar celulele de deasupra diagonalei, iar diagonala nu se atinge.

Din subiectele de BAC

Exerciții reale din subiectele anilor trecuți. Încearcă-le singur înainte să deschizi rezolvarea.

Indicați o declarare a unui tablou bidimensional m, care poate memora maximum 100 de numere reale.

a. float m[2,50]; b. float m[4][25]; c. float m[10] x float m[10]; d. int m[100];

Vezi rezolvarea

Cerința are trei condiții: tabloul trebuie să fie bidimensional, să memoreze numere reale și să aibă cel mult 100 de elemente.

  • a. float m[2,50]; - în C/C++ virgula dintre paranteze este operatorul virgulă, nu un separator de dimensiuni; declarația este echivalentă cu float m[50];, deci un tablou unidimensional.
  • b. float m[4][25]; - bidimensional, elemente reale, 4⋅25=1004 \cdot 25 = 100 elemente. Corect.
  • c. float m[10] x float m[10]; - nu este o sintaxă C/C++ validă.
  • d. int m[100]; - unidimensional și cu elemente întregi.

Răspunsul corect este litera b.

Variabilele i și j sunt de tip întreg, iar variabila a memorează un tablou bidimensional cu 9 linii și 9 coloane, numerotate începând de la 0, având inițial toate elementele nule. Scrieți secvența de instrucțiuni de mai jos, înlocuind punctele de suspensie cu instrucțiuni adecvate, dintre care cel mult patru de atribuire, astfel încât, în urma executării secvenței obținute, variabila a să memoreze tabloul alăturat.

for(i=0;i<9;i++)
   for(j=0;j<9;j++)
      ..................

Tabloul cerut (liniile 0-8):

4 4 4 4 2 2 2 2 2
4 4 4 2 2 2 2 2 2
4 4 2 2 2 2 2 2 2
4 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 4
2 2 2 2 2 2 2 4 4
2 2 2 2 2 2 4 4 4
2 2 2 2 2 4 4 4 4
Vezi rezolvarea

Observăm poziția valorilor 4: în colțul din stânga-sus apar exact acolo unde i+j≤3i + j \le 3 (pe linia 0 primele 4 coloane, pe linia 1 primele 3 etc.), iar în colțul din dreapta-jos exact acolo unde i+j≥13i + j \ge 13 (pe linia 5 doar coloana 8, pe linia 8 coloanele 5-8). În rest, elementele sunt 2.

Secvența completată, cu două instrucțiuni de atribuire:

for(i=0;i<9;i++)
   for(j=0;j<9;j++)
      if(i+j<=3 || i+j>=13)
         a[i][j]=4;
      else
         a[i][j]=2;

Pentru a identifica punctele în care se concentrează apa în albia unui râu în cazul secetei, se determină talvegul acesteia, adică linia care unește punctele cele mai adânci ale albiei. În acest scop s-au stabilit ns secțiuni transversale pe cursul apei, numerotate începând de la 1, și în cadrul fiecărei secțiuni s-a măsurat adâncimea apei în np puncte, numerotate începând de la 1. Din fiecare secțiune, în ordine, se include în talveg cel mai adânc punct al acesteia, iar dacă în secțiune sunt mai multe puncte aflate la aceeași adâncime, maximă, se va lua în considerare doar primul dintre ele.

Scrieți un program C/C++ care citește de la tastatură două numere naturale, ns și np (ns∈[1,103]ns \in [1,10^3], np∈[1,50]np \in [1,50]), și cele ns⋅npns \cdot np elemente ale unui tablou bidimensional, valori naturale din intervalul [0,102][0,10^2]. Fiecare linie a tabloului corespunde câte unei secțiuni, în ordinea numerotării acestora, iar valorile memorate pe linie reprezintă adâncimile celor np puncte stabilite pentru acea secțiune, în ordinea numerotării lor. Programul afișează pe ecran, pentru fiecare secțiune, o pereche formată din numărul de ordine al secțiunii și numărul de ordine al punctului său care s-a inclus în talveg. Numerele din fiecare pereche sunt afișate separate prin câte un caracter : (două puncte), iar fiecare pereche este urmată de un spațiu.

Exemplu: pentru ns=6, np=4 și tabloul cu liniile (2 4 5 3), (2 6 6 3), (1 5 2 5), (1 3 3 3), (3 4 3 5), (0 1 2 1), se afișează pe ecran valorile: 1:3 2:2 3:2 4:2 5:4 6:3

Vezi rezolvarea
#include <iostream>
using namespace std;

int main() {
    int ns, np, a[1001][51];
    cin >> ns >> np;
    for (int i = 1; i <= ns; i++)
        for (int j = 1; j <= np; j++)
            cin >> a[i][j];
    for (int i = 1; i <= ns; i++) {
        int pmax = 1;
        for (int j = 2; j <= np; j++)
            if (a[i][j] > a[i][pmax])
                pmax = j;
        cout << i << ":" << pmax << " ";
    }
    return 0;
}

Comparația strictă a[i][j] > a[i][pmax] garantează că, la adâncimi egale, rămâne selectat primul punct de adâncime maximă din secțiune. Pentru exemplul dat se afișează 1:3 2:2 3:2 4:2 5:4 6:3.

Toate lecțiile de Informatică

Descarcă

Începe azi. Bacul nu așteaptă.

Descarcă Tomomi pe telefonul copilului tău și pornește perioada de probă gratuită.