Sari la conținut

Capitolul 8 · Lecția 8.2 din 2

Vecinii unei celule și bordarea matricei

Tehnica direcțiilor dx/dy și bordarea cu santinelă pentru probleme de vecinătate.

Capitolul 8: Tablouri bidimensionaleConținut verificat

Pe scurt pentru BAC · 4 idei

  • Vecinii pe 4 direcții se parcurg cu vectorii dx și dy într-o singură buclă for (int d = 0; d < 4; d++).
  • Pentru 8 vecini, cu tot cu diagonalele, extinzi vectorii de direcție la 8 perechi.
  • Bordarea înconjoară matricea cu un cadru de valori neutre și lucrezi cu indicii de la 1 la n, astfel încât a[i-1][j] există mereu.
  • Sumele pe vecinătăți, elementele izolate și drumurile în matrice se reduc la dx/dy cu verificarea limitelor sau la bordare.
Pe această pagină5 secțiuni

Vecinii unei celule

Tehnica standard: vectorii de direcție.

Cei patru vecini ai unei celule

#include <iostream>
using namespace std;

int main() {
    int a[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, n = 3, m = 3;
    int i = 1, j = 1, s = 0;
    int dx[] = {-1, 1, 0, 0};
    int dy[] = {0, 0, 1, -1};
    for (int d = 0; d < 4; d++) {
        int ni = i + dx[d], nj = j + dy[d];
        if (ni >= 0 && ni < n && nj >= 0 && nj < m)
            s += a[ni][nj];
    }
    cout << s;
    return 0;
}

Atenție: Verificarea marginilor e obligatorie. Fara ea, pentru o celula de pe margine s-ar citi in afara matricei.

se trimit programului la citire

Pentru 8 vecini (cu diagonale), extinzi vectorii la 8 perechi.

Bordarea (santinela)

Alternativa elegantă la verificarea limitelor: ÎNCONJORI matricea cu un cadru de valori neutre (0 sau o valoare care nu deranjează) și lucrezi cu indicii 1..n:

Bordarea matricei

#include <iostream>
using namespace std;

int main() {
    int a[5][5] = {0};
    int n = 3, m = 3;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            a[i][j] = (i - 1) * m + j;
    int s = 0;
    for (int d = 0; d < 4; d++) {
        int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, 1, -1};
        s += a[2 + dx[d]][2 + dy[d]];
    }
    cout << s;
    return 0;
}

Atenție: Bordarea inseamna a lasa in jurul matricei o rama de zerouri. Asa nu mai trebuie verificate marginile: vecinii din afara exista si valoreaza zero.

se trimit programului la citire

Acum a[i-1][j] există întotdeauna pentru i din 1..n: dispar toate condițiile de margine.

Exemplu rezolvat

Matricea 3×3 cu valorile 1..9 (pe linii). Suma vecinilor pe 4 direcții ai celulei centrale (valoarea 5): vecinii sunt 2 (N), 8 (S), 6 (E), 4 (V): suma 20.

Unde apare la BAC

Sume pe vecinătăți, numărarea elementelor "izolate" (mai mari decât toți vecinii), drumuri în matrice, jocuri de viață simplificate: toate se reduc la dx/dy + verificarea limitelor sau bordare.

Reține

dx/dy transformă 4 (sau 8) cazuri copy-paste într-o buclă de 4 (8) pași. Bordarea cu 0 elimină complet verificările de margine la sume.

Greșeli frecvente

  1. Fără verificarea limitelor, colțurile citesc memorie din afara matricei.
  2. La bordare, valorile santinelei trebuie NEUTRE pentru operație (0 la sumă, dar -infinit la maxim!).
  3. Perechile dx/dy se parcurg sincron: dx[d] cu dy[d], nu combinații încrucișate.

Instrumente pentru lecția asta

Parcurgerea matricei

Pe linii, pe coloane, diagonalele și bordarea, animate celulă cu celulă, cu codul C++ corespunzător fiecărei parcurgeri.

Se încarcă instrumentul…

Bifează când ai terminat, ca s-o vezi citită pe toate dispozitivele.

Testează-te pe capitolul 8

Lecția în clipuri

Clipuri scurte, cu voce și subtitrări.

Folosim cookie-uri esențiale, fără de care site-ul nu merge, și cookie-uri de analiză anonimizate, ca să vedem ce pagini ajută. Detalii în politica de confidențialitate