Bordura și interiorul matricei
Multe probleme cer să procesăm doar anumite părți ale matricei: marginile (bordura) sau elementele din interior. În această lecție învățăm cum să le identificăm și parcurgem.
Ce este bordura?
Bordura (sau marginea) matricei conține elementele de pe:
- Prima linie (
i == 1) - Ultima linie (
i == n) - Prima coloană (
j == 1) - Ultima coloană (
j == m)
Matrice 4 x 5:
[*] [*] [*] [*] [*]
[*] . . . [*]
[*] . . . [*]
[*] [*] [*] [*] [*]
Condiția
Un element a[i][j] este pe bordură dacă:
i == 1 || i == n || j == 1 || j == mAfișarea bordurii
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
if (i == 1 || i == n || j == 1 || j == m)
fout << a[i][j] << " ";Suma bordurii
int suma = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
if (i == 1 || i == n || j == 1 || j == m)
suma = suma + a[i][j];
fout << suma;Parcurgerea bordurii eficient (fără condiție)
În loc să verificăm fiecare element, parcurgem direct cele 4 laturi:
// Prima linie
for (int j = 1; j <= m; j++)
fout << a[1][j] << " ";
// Ultima linie
for (int j = 1; j <= m; j++)
fout << a[n][j] << " ";
// Prima coloana (fără colțuri, deja parcurse)
for (int i = 2; i < n; i++)
fout << a[i][1] << " ";
// Ultima coloana (fără colțuri)
for (int i = 2; i < n; i++)
fout << a[i][m] << " ";Atenție la colțuri: dacă parcurgi separat
cele 4 laturi, colțurile (a[1][1],
a[1][m], a[n][1],
a[n][m]) pot fi numărate de două ori. De aceea, la
prima/ultima coloană începem de la i = 2 și
terminăm la i = n - 1.
Ce este interiorul?
Interiorul conține toate elementele care nu sunt pe bordură:
. . . . .
. [*] [*] [*] .
. [*] [*] [*] .
. . . . .
Condiția
i > 1 && i < n && j > 1 && j < mSau mai simplu - parcurgem de la linia 2 la n-1 și coloana 2 la m-1:
for (int i = 2; i < n; i++)
for (int j = 2; j < m; j++)
fout << a[i][j] << " ";Suma interiorului
int suma = 0;
for (int i = 2; i < n; i++)
for (int j = 2; j < m; j++)
suma = suma + a[i][j];
fout << suma;Borduri concentrice (cadre)
Unele probleme cer să procesăm cadrul k al
matricei - bordura de la distanța k de margine.
Cadrul 0 (bordura exterioară):
[*] [*] [*] [*] [*]
[*] . . . [*]
[*] . . . [*]
[*] . . . [*]
[*] [*] [*] [*] [*]
Cadrul 1:
. . . . .
. [*] [*] [*] .
. [*] . [*] .
. [*] [*] [*] .
. . . . .
Cadrul k
Elementul a[i][j] aparține cadrului
k dacă:
i == k + 1 || i == n - k || j == k + 1 || j == m - kȘi se află în interiorul cadrelor anterioare:
i >= k + 1 && i <= n - k && j >= k + 1 && j <= m - kParcurgerea cadrului k
void parcurgeCadru(int a[][101], int n, int m, int k) {
// Linia de sus
for (int j = k + 1; j <= m - k; j++)
fout << a[k + 1][j] << " ";
// Coloana din dreapta
for (int i = k + 2; i <= n - k; i++)
fout << a[i][m - k] << " ";
// Linia de jos (invers)
for (int j = m - k - 1; j >= k + 1; j--)
fout << a[n - k][j] << " ";
// Coloana din stânga (invers)
for (int i = n - k - 1; i >= k + 2; i--)
fout << a[i][k + 1] << " ";
}Exemplu complet: verificare cadru magic
Verificăm dacă suma bordurii este egală cu suma interiorului.
#include <fstream>
using namespace std;
ifstream fin("date.in");
ofstream fout("date.out");
int a[101][101];
int n, m;
int main()
{
fin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
fin >> a[i][j];
int sumaBordura = 0;
int sumaInterior = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
if (i == 1 || i == n || j == 1 || j == m)
sumaBordura = sumaBordura + a[i][j];
else
sumaInterior = sumaInterior + a[i][j];
}
fout << "Bordura: " << sumaBordura << endl;
fout << "Interior: " << sumaInterior << endl;
if (sumaBordura == sumaInterior)
fout << "EGALE";
else
fout << "DIFERITE";
return 0;
}Modificarea bordurii
Setarea bordurii la o valoare
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
if (i == 1 || i == n || j == 1 || j == m)
a[i][j] = 0;Incrementarea bordurii
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
if (i == 1 || i == n || j == 1 || j == m)
a[i][j]++;Greșeli frecvente
1. Interiorul gol pe matrici mici
Dacă matricea are 1 sau 2 linii/coloane, nu are
interior. Bucla
for (int i = 2; i < n; ...) nu se execută.
2. Colțuri numărate dublu
Când parcurgi bordura linie cu linie + coloană cu coloană,
colțurile apar de două ori. Folosește condiția unificată
i == 1 || i == n || j == 1 || j == m sau ajustează
limitele buclelor.
3. Confuzia n vs
m
- Liniile merg de la 1 la
n - Coloanele merg de la 1 la
m
La bordură: prima linie i == 1, ultima
i == n, prima coloană j == 1, ultima
j == m.
Ce să reții
- Bordura:
i == 1 || i == n || j == 1 || j == m. - Interiorul:
i > 1 && i < n && j > 1 && j < m(sau buclă de la 2 la n-1). - Parcurgerea eficientă a bordurii: cele 4 laturi separat, atenție la colțuri.
- Cadrele concentrice: borduri la distanță k de margine.
- Pe matrici mici (1x1, 2x2), interiorul poate fi gol.