Estructuras de Datosc++matricesarreglosbidimensionalestructuras-de-datos
Matrices (Arreglos Bidimensionales)
Aprende a trabajar con matrices y arreglos bidimensionales en C++
OOI Oaxaca9 de febrero de 20268 min read
¿Qué es una matriz?
Una matriz es un arreglo bidimensional organizado en filas y columnas. Puedes pensar en ella como una tabla o cuadrícula.
Matriz 3x4 (3 filas, 4 columnas):
col 0 col 1 col 2 col 3
┌───────┬───────┬───────┬───────┐
fila 0 │ 1 │ 2 │ 3 │ 4 │
├───────┼───────┼───────┼───────┤
fila 1 │ 5 │ 6 │ 7 │ 8 │
├───────┼───────┼───────┼───────┤
fila 2 │ 9 │ 10 │ 11 │ 12 │
└───────┴───────┴───────┴───────┘
Declaración
Arreglo tradicional
int matriz[3][4]; // 3 filas, 4 columnas
// Con inicialización
int matriz[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
Vector de vectores (recomendado)
#include <vector>
using namespace std;
// Declaración vacía
vector<vector<int>> matriz;
// Con tamaño inicial (n filas, m columnas, valor 0)
vector<vector<int>> matriz(n, vector<int>(m, 0));
// Con inicialización
vector<vector<int>> matriz = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
Acceso a elementos
int matriz[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
cout << matriz[0][0] << endl; // 1 (fila 0, columna 0)
cout << matriz[1][2] << endl; // 7 (fila 1, columna 2)
cout << matriz[2][3] << endl; // 12 (fila 2, columna 3)
matriz[1][1] = 100; // Modificar elemento
Recorrer una matriz
Con for tradicional
int n = 3, m = 4;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cout << matriz[i][j] << " ";
}
cout << endl;
}
Con range-based for
vector<vector<int>> matriz = {{1,2,3}, {4,5,6}};
for (auto& fila : matriz) {
for (int elemento : fila) {
cout << elemento << " ";
}
cout << endl;
}
Lectura desde entrada
int n, m;
cin >> n >> m;
vector<vector<int>> matriz(n, vector<int>(m));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> matriz[i][j];
}
}
Operaciones comunes
Suma de todos los elementos
int suma = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
suma += matriz[i][j];
}
}
Elemento máximo
int maximo = matriz[0][0];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
maximo = max(maximo, matriz[i][j]);
}
}
Suma por filas
for (int i = 0; i < n; i++) {
int sumaFila = 0;
for (int j = 0; j < m; j++) {
sumaFila += matriz[i][j];
}
cout << "Fila " << i << ": " << sumaFila << endl;
}
Suma por columnas
for (int j = 0; j < m; j++) {
int sumaCol = 0;
for (int i = 0; i < n; i++) {
sumaCol += matriz[i][j];
}
cout << "Columna " << j << ": " << sumaCol << endl;
}
Matrices cuadradas
Una matriz cuadrada tiene el mismo número de filas y columnas.
Diagonal principal
// Elementos donde i == j
for (int i = 0; i < n; i++) {
cout << matriz[i][i] << " ";
}
Diagonal secundaria
// Elementos donde i + j == n - 1
for (int i = 0; i < n; i++) {
cout << matriz[i][n - 1 - i] << " ";
}
Traza (suma de diagonal)
int traza = 0;
for (int i = 0; i < n; i++) {
traza += matriz[i][i];
}
Recorridos especiales
Por diagonales
// Todas las diagonales paralelas a la principal
int n = matriz.size();
int m = matriz[0].size();
for (int d = 0; d < n + m - 1; d++) {
int fila = max(0, d - m + 1);
int col = max(0, m - 1 - d);
while (fila < n && col < m) {
cout << matriz[fila][col] << " ";
fila++;
col++;
}
cout << endl;
}
En espiral
vector<int> recorridoEspiral(vector<vector<int>>& matriz) {
vector<int> resultado;
if (matriz.empty()) return resultado;
int top = 0, bottom = matriz.size() - 1;
int left = 0, right = matriz[0].size() - 1;
while (top <= bottom && left <= right) {
// Derecha
for (int i = left; i <= right; i++)
resultado.push_back(matriz[top][i]);
top++;
// Abajo
for (int i = top; i <= bottom; i++)
resultado.push_back(matriz[i][right]);
right--;
// Izquierda
if (top <= bottom) {
for (int i = right; i >= left; i--)
resultado.push_back(matriz[bottom][i]);
bottom--;
}
// Arriba
if (left <= right) {
for (int i = bottom; i >= top; i--)
resultado.push_back(matriz[i][left]);
left++;
}
}
return resultado;
}
Aplicación: Cuadrícula (Grid)
Las cuadrículas son muy comunes en problemas de competencia.
Movimientos en 4 direcciones
int dx[] = {0, 0, 1, -1}; // derecha, izquierda, abajo, arriba
int dy[] = {1, -1, 0, 0};
// Desde posición (x, y), visitar vecinos
for (int d = 0; d < 4; d++) {
int nx = x + dx[d];
int ny = y + dy[d];
// Verificar límites
if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
// Procesar vecino (nx, ny)
}
}
Movimientos en 8 direcciones
int dx[] = {-1, -1, -1, 0, 0, 1, 1, 1};
int dy[] = {-1, 0, 1, -1, 1, -1, 0, 1};
for (int d = 0; d < 8; d++) {
int nx = x + dx[d];
int ny = y + dy[d];
// ...
}
Ejemplo: Rotar matriz 90°
void rotar90(vector<vector<int>>& matriz) {
int n = matriz.size();
// Transponer
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
swap(matriz[i][j], matriz[j][i]);
}
}
// Invertir cada fila
for (int i = 0; i < n; i++) {
reverse(matriz[i].begin(), matriz[i].end());
}
}
Ejemplo: Buscar en matriz ordenada
Matriz donde cada fila y columna está ordenada:
bool buscar(vector<vector<int>>& matriz, int objetivo) {
if (matriz.empty()) return false;
int n = matriz.size();
int m = matriz[0].size();
// Empezar desde esquina superior derecha
int fila = 0, col = m - 1;
while (fila < n && col >= 0) {
if (matriz[fila][col] == objetivo) {
return true;
} else if (matriz[fila][col] < objetivo) {
fila++; // El objetivo está abajo
} else {
col--; // El objetivo está a la izquierda
}
}
return false;
}
Ejemplo: Flood Fill (pintar región)
void floodFill(vector<vector<int>>& imagen, int sr, int sc, int nuevoColor) {
int colorOriginal = imagen[sr][sc];
if (colorOriginal == nuevoColor) return;
int n = imagen.size(), m = imagen[0].size();
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
function<void(int, int)> dfs = [&](int x, int y) {
if (x < 0 || x >= n || y < 0 || y >= m) return;
if (imagen[x][y] != colorOriginal) return;
imagen[x][y] = nuevoColor;
for (int d = 0; d < 4; d++) {
dfs(x + dx[d], y + dy[d]);
}
};
dfs(sr, sc);
}
Ejercicios de práctica
Ejercicio 1
Verifica si una matriz es simétrica (igual a su transpuesta).
Ver solución
bool esSimetrica(vector<vector<int>>& matriz) {
int n = matriz.size();
for (int i = 0; i < n; i++) {
for (int j = 0; j < i; j++) {
if (matriz[i][j] != matriz[j][i]) {
return false;
}
}
}
return true;
}
Ejercicio 2
Cuenta el número de islas en una cuadrícula (grupos de 1s conectados).
Ver solución
int contarIslas(vector<vector<int>>& grid) {
int n = grid.size(), m = grid[0].size();
int islas = 0;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
function<void(int, int)> dfs = [&](int x, int y) {
if (x < 0 || x >= n || y < 0 || y >= m || grid[x][y] == 0) return;
grid[x][y] = 0; // Marcar como visitado
for (int d = 0; d < 4; d++) {
dfs(x + dx[d], y + dy[d]);
}
};
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] == 1) {
islas++;
dfs(i, j);
}
}
}
return islas;
}
Siguiente paso
Aprende sobre Algoritmos de Ordenamiento para organizar datos eficientemente.
