Matrices
Aprende a trabajar con arreglos bidimensionales y matrices en C++
¿Qué es una matriz?
Si un arreglo es una fila de casilleros, una matriz es una cuadrícula de casilleros con filas y columnas. Piensa en un tablero de ajedrez, un campo de minas, una hoja de cálculo de Excel, o la pantalla de píxeles de tu computadora.
Matriz 3×4:
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 ]
Para acceder a un elemento, necesitas dos índices: la fila y la columna. mat[1][2] es el elemento en la fila 1, columna 2, que en el ejemplo es 7.
Declarar matrices
Arreglo estático 2D
int mat[3][4]; // Matriz 3×4 sin inicializar
int mat[3][4] = {{0}}; // Matriz 3×4 toda en ceros
int mat[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
Con vectores (más flexible)
int filas = 3, cols = 4;
vector<vector<int>> mat(filas, vector<int>(cols, 0)); // 3×4, todo ceros
Global (recomendado en competencias)
const int MAXN = 1001;
int mat[MAXN][MAXN]; // Se inicializa a 0 automáticamente por ser global
Leer y escribir matrices
Leer
int n, m; // n filas, m columnas
cin >> n >> m;
int mat[1001][1001];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> mat[i][j];
}
}
Escribir
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (j > 0) cout << " ";
cout << mat[i][j];
}
cout << '\n';
}
Recorridos de una matriz
Recorrer por filas (lo más natural)
for (int i = 0; i < n; i++) { // Para cada fila
for (int j = 0; j < m; j++) { // Para cada columna
// Procesar mat[i][j]
}
}
Recorrer por columnas
for (int j = 0; j < m; j++) { // Para cada columna
for (int i = 0; i < n; i++) { // Para cada fila
// Procesar mat[i][j]
}
}
Recorrer la diagonal principal
// Solo funciona si es cuadrada (n×n)
for (int i = 0; i < n; i++) {
cout << mat[i][i] << " ";
}
Recorrer la diagonal secundaria
for (int i = 0; i < n; i++) {
cout << mat[i][n - 1 - i] << " ";
}
Los 4 (u 8) vecinos
En muchos problemas, necesitas visitar las celdas vecinas de una posición (i, j):
(i-1,j)
↑
(i,j-1) ← (i,j) → (i,j+1)
↓
(i+1,j)
4 vecinos (arriba, abajo, izquierda, derecha)
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
for (int d = 0; d < 4; d++) {
int ni = i + dx[d];
int nj = j + dy[d];
// Verificar que esté dentro de los límites
if (ni >= 0 && ni < n && nj >= 0 && nj < m) {
// mat[ni][nj] es un vecino válido
}
}
8 vecinos (incluye diagonales)
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 ni = i + dx[d];
int nj = j + dy[d];
if (ni >= 0 && ni < n && nj >= 0 && nj < m) {
// Procesar vecino mat[ni][nj]
}
}
Problemas clásicos con matrices
1. Suma de elementos
int suma = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
suma += mat[i][j];
2. Transponer una matriz
La transpuesta intercambia filas por columnas: mat[i][j] se convierte en mat[j][i].
int transpuesta[1001][1001];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
transpuesta[j][i] = mat[i][j];
3. Rotar 90 grados (en sentido horario)
int rotada[1001][1001];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
rotada[j][n - 1 - i] = mat[i][j];
4. Matriz de cuadrícula (grid) como mapa
Muchos problemas representan mapas como matrices de caracteres:
5 5
.....
.###.
.#...
.###.
.....
int n, m;
cin >> n >> m;
char grid[1001][1001];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> grid[i][j];
}
}
// O leer como strings
string grid2[1001];
for (int i = 0; i < n; i++) {
cin >> grid2[i];
}
// Acceso: grid2[i][j]
5. Suma de prefijos 2D
Para responder rápidamente "¿cuál es la suma del subrectángulo de (r1,c1) a (r2,c2)?":
// Construir la tabla de prefijos
int prefix[1001][1001] = {0};
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
prefix[i][j] = mat[i][j]
+ prefix[i-1][j]
+ prefix[i][j-1]
- prefix[i-1][j-1];
}
}
// Consultar suma del subrectángulo (r1,c1) a (r2,c2)
int suma = prefix[r2][c2]
- prefix[r1-1][c2]
- prefix[r2][c1-1]
+ prefix[r1-1][c1-1];
Esto permite responder cada consulta en después de de preprocesamiento.
Ejercicio de práctica
Lee una matriz de N×M y encuentra el valor máximo junto con su posición (fila y columna).
Entrada:
3 4
1 2 3 4
5 6 7 8
9 10 11 12
Salida: 12 2 3 (el máximo es 12, en fila 2, columna 3, contando desde 0)
Ver solución
#include <iostream>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
int mat[1001][1001];
int maxVal = -1e9;
int maxFila = 0, maxCol = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> mat[i][j];
if (mat[i][j] > maxVal) {
maxVal = mat[i][j];
maxFila = i;
maxCol = j;
}
}
}
cout << maxVal << " " << maxFila << " " << maxCol << endl;
return 0;
}
Siguiente paso
Aprende sobre Structs para crear tus propios tipos de datos combinados.
