Prerrequisitos y Entorno de Ejecución Requerido¶
Para compilar y verificar las soluciones de este módulo bajo el estándar C11 estricto de cátedra, se requiere:
Compilador C11: GCC 9+ o Clang 11+ configurado con flags
-Wall -Wextra -Werror -pedantic -std=c11.Entorno POSIX: Linux o WSL con utilidades estándar, soporte de arreglos multidimensionales y memoria dinámica.
Herramientas de Verificación: Valgrind (memcheck) y AddressSanitizer (
-fsanitize=address,undefined) para garantizar la ausencia de desbordamientos de búfer en indexación bidimensional.Conocimientos Previos: Arreglos unidimensionales contiguos, punteros, orden por filas (row-major order), aplanamiento de matrices y aritmética de punteros.
Objetivos Pedagógicos y Competencias (Taxonomía de Bloom)¶
Nivel 2 (Comprensión): Comprender el mapeo bidimensional a memoria física contigua mediante la fórmula
f * cols + c.Nivel 3 (Aplicación): Implementar algoritmos de formateo, trasposición, multiplicación, rotación y recorrido diagonal en C11.
Nivel 4 (Análisis): Evaluar el impacto de la localidad espacial de caché y la complejidad en lazos anidados.
Andamiaje Progresivo: Ejercicios andamiados con contratos formales (precondiciones/postcondiciones), tablas de vectores de prueba y suites ejecutables con
assert().
Capítulos de Apunte Correspondientes¶
capitulo-arreglos
Cuestiones de Estilo Aplicables¶
Calificador const: Toda matriz de entrada cuyos valores no deban modificarse debe calificarse como
const int *matrizoconst int mat[][COLS].Dimensiones size_t: Las filas y columnas deben expresarse con
size_t.
Operaciones Básicas¶
Ejercicio 3.01.01 - Formateo de Matriz Plana ⭐⭐⭐☆☆¶
(ej_b3_c01_02)=
### Ejercicio 3.01.02 - Multiplicación por un Escalar in-place ⭐⭐☆☆☆
:::{exercise}
:label: ej_b3_c01_02_escalar
Implementá una función que multiplique cada componente de una matriz plana
por un entero escalar dado, modificando el arreglo en memoria (*in-place*).
```c
void matriz_multiplicar_escalar(int *mat, size_t filas, size_t cols, int escalar);
```
**Tabla de Vectores de Prueba:**
| Matriz Inicial ($2 \times 2$) | Escalar | Matriz Resultante |
| :--- | :--- | :--- |
| `[1, 2, 3, 4]` | `5` | `[5, 10, 15, 20]` |
| `[10, -2, 0, 8]` | `-1` | `[-10, 2, 0, -8]` |
| `[5, 10]` | `0` | `[0, 0]` |
::::{solution}
```c
#include <stdio.h>
#include <stddef.h>
#include <assert.h>
void matriz_multiplicar_escalar(int *mat, size_t filas, size_t cols, int escalar) {
if (mat == NULL) {
return;
}
size_t total = filas * cols;
for (size_t i = 0; i < total; ++i) {
mat[i] *= escalar;
}
}
int main(void) {
int m[4] = {1, 2, 3, 4};
matriz_multiplicar_escalar(m, 2, 2, 5);
assert(m[0] == 5 && m[1] == 10 && m[2] == 15 && m[3] == 20);
int m2[4] = {10, -2, 0, 8};
matriz_multiplicar_escalar(m2, 2, 2, -1);
assert(m2[0] == -10 && m2[1] == 2 && m2[2] == 0 && m2[3] == -8);
matriz_multiplicar_escalar(m, 2, 2, 0);
for (size_t i = 0; i < 4; ++i) assert(m[i] == 0);
return 0;
}
```
## Aritmética Matricial
(ej_b3_c01_03)=
### Ejercicio 3.01.03 - Suma de matrices ⭐⭐⭐☆☆
:::{exercise}
:label: ej_b3_c01_03_suma_matrices
Implementá una función que sume dos matrices planas contiguas de enteros, `a` y `b`,
almacenando el resultado en una tercera matriz de destino `c` de idénticas dimensiones:
```c
void matriz_sumar(const int *a, const int *b, int *c, size_t filas, size_t cols);
```
**Tabla de Vectores de Prueba:**
| Dimensiones | Matriz A | Matriz B | Matriz C (Salida) |
| :--- | :--- | :--- | :--- |
| $2 \times 2$ | `[1, 2, 3, 4]` | `[5, 6, 7, 8]` | `[6, 8, 10, 12]` |
| $1 \times 3$ | `[10, -5, 0]` | `[-10, 5, 42]` | `[0, 0, 42]` |
| $0 \times 0$ | `NULL` | `NULL` | Sin modificaciones |
::::{solution}
```c
#include <stdio.h>
#include <stddef.h>
#include <assert.h>
void matriz_sumar(const int *a, const int *b, int *c, size_t filas, size_t cols) {
if (a == NULL || b == NULL || c == NULL) {
return;
}
size_t total = filas * cols;
for (size_t i = 0; i < total; ++i) {
c[i] = a[i] + b[i];
}
}
int main(void) {
int a[4] = {1, 2, 3, 4};
int b[4] = {5, 6, 7, 8};
int c[4] = {0};
matriz_sumar(a, b, c, 2, 2);
assert(c[0] == 6 && c[1] == 8 && c[2] == 10 && c[3] == 12);
int a2[3] = {10, -5, 0};
int b2[3] = {-10, 5, 42};
int c2[3] = {0};
matriz_sumar(a2, b2, c2, 1, 3);
assert(c2[0] == 0 && c2[1] == 0 && c2[2] == 42);
matriz_sumar(NULL, NULL, NULL, 0, 0);
return 0;
}
```
(ej_b3_c01_04)=
### Ejercicio 3.01.04 - Multiplicación de matrices ⭐⭐⭐☆☆
:::{exercise}
:label: ej_b3_c01_04_multiplicacion_matrices
Implementá la multiplicación de dos matrices planas contiguas en C11:
- Matriz $A$ de dimensiones $m \times n$.
- Matriz $B$ de dimensiones $n \times p$.
- Matriz resultado $C$ de dimensiones $m \times p$.
```c
void matriz_multiplicar(const int *a, const int *b, int *c, size_t m, size_t n, size_t p);
```
**Tabla de Vectores de Prueba:**
| Dimensiones | Matriz A | Matriz B | Matriz C (Salida) |
| :--- | :--- | :--- | :--- |
| $2 \times 3 \times 2$ | `[[1, 2, 3], [4, 5, 6]]` | `[[7, 8], [9, 10], [11, 12]]` | `[[58, 64], [139, 154]]` |
| $2 \times 2 \times 2$ (Identidad) | `[[1, 2], [3, 4]]` | `[[1, 0], [0, 1]]` | `[[1, 2], [3, 4]]` |
| $0 \times 0 \times 0$ | `NULL` | `NULL` | Sin modificaciones |
::::{solution}
```c
#include <stdio.h>
#include <stddef.h>
#include <assert.h>
void matriz_multiplicar(const int *a, const int *b, int *c, size_t m, size_t n, size_t p) {
if (a == NULL || b == NULL || c == NULL || m == 0 || n == 0 || p == 0) {
return;
}
for (size_t i = 0; i < m; ++i) {
for (size_t j = 0; j < p; ++j) {
int suma = 0;
for (size_t k = 0; k < n; ++k) {
suma += a[i * n + k] * b[k * p + j];
}
c[i * p + j] = suma;
}
}
}
int main(void) {
int a[6] = {1, 2, 3, 4, 5, 6}; // 2x3
int b[6] = {7, 8, 9, 10, 11, 12}; // 3x2
int c[4] = {0}; // 2x2
matriz_multiplicar(a, b, c, 2, 3, 2);
assert(c[0] == 58 && c[1] == 64 && c[2] == 139 && c[3] == 154);
int m2[4] = {1, 2, 3, 4};
int id[4] = {1, 0, 0, 1};
int res[4] = {0};
matriz_multiplicar(m2, id, res, 2, 2, 2);
assert(res[0] == 1 && res[1] == 2 && res[2] == 3 && res[3] == 4);
matriz_multiplicar(NULL, NULL, NULL, 0, 0, 0);
return 0;
}
```
## Manipulación
(ej_b3_c01_05)=
### Ejercicio 3.01.05 - Transposición ⭐⭐☆☆☆
#### Descripción
Calcular la transpuesta $A^T$ de una matriz $A$. La transposición se obtiene
intercambiando las filas por las columnas.
::::{tab-set}
:::{tab-item} Entrada
:sync: tab1
``` text
Matriz A (2x3): `[[1, 2, 3], [4, 5, 6]]`
```
<!-- text -->
Matriz (3x2):
[ 1, 4 ]
[ 2, 5 ]
[ 3, 6 ]<!-- {tab-set} -->
:::{hint} Lógica y Consideraciones
- **Fórmula:** $(A^T)_{ij} = A_{ji}$.
- **Dimensiones:** Si la matriz original es $m \times n$, su transpuesta será
$n \times m$.
- **Proceso:** Recorrer la matriz original `A` con lazos anidados. En cada
posición `(i, j)`, copiar el elemento `A[i][j]` a la posición `(j, i)` de la
nueva matriz transpuesta.
:::
<!-- {hint} Lógica y Consideraciones -->
:::{hint} Lógica y Consideraciones
:class: dropdown
```{code-block} pseudocode
:linenos:
PROCEDIMIENTO transponer_matriz(A, filas, columnas, REF A_T)
INICIO
PARA i DESDE 0 HASTA filas-1 HACER
PARA j DESDE 0 HASTA columnas-1 HACER
A_T[j][i] = A[i][j]
FIN PARA
FIN PARA
FIN PROCEDIMIENTO
```
<!-- {code-block} pseudocode -->
:::
<!-- {hint} Lógica y Consideraciones -->
(ej_b3_c01_06)=
### Ejercicio 3.01.06 - Suma de diagonales ⭐⭐☆☆☆
#### Descripción
Para una matriz cuadrada, calcular la suma de los elementos de sus dos
diagonales: la principal y la secundaria.
::::{tab-set}
:::{tab-item} Entrada
:sync: tab1
Matriz (3x3):
``` text
[ 1, 2, 3 ]
[ 4, 5, 6 ]
[ 7, 8, 9 ]
```
<!-- text -->
:::
<!-- {tab-item} Entrada -->
:::{tab-item} Salida
:sync: tab2
``` text
Suma Diagonal Principal: `1 + 5 + 9 = 15`
Suma Diagonal Secundaria: `3 + 5 + 7 = 15`
```
<!-- text -->
:::
<!-- {tab-item} Salida -->
Lógica y Consideraciones
1 2 3 4 5 6 7 8 9PROCEDIMIENTO sumar_diagonales(matriz, n, REF suma_princ, REF suma_sec) INICIO suma_princ = 0 suma_sec = 0 PARA i DESDE 0 HASTA n-1 HACER suma_princ = suma_princ + matriz[i][i] suma_sec = suma_sec + matriz[i][n-1-i] FIN PARA FIN PROCEDIMIENTO
Generación¶
Ejercicio 3.01.07 - Matriz identidad ⭐⭐⭐☆☆¶
Descripción¶
Generar una matriz identidad de tamaño n x n. La matriz identidad es una
matriz cuadrada con unos en la diagonal principal y ceros en todas las demás
posiciones.
Tamaño n = 3[ 1, 0, 0 ]
[ 0, 1, 0 ]
[ 0, 0, 1 ]Lógica y Consideraciones
1 2 3 4 5 6 7 8 9 10 11 12PROCEDIMIENTO generar_identidad(REF matriz, n) INICIO PARA i DESDE 0 HASTA n-1 HACER PARA j DESDE 0 HASTA n-1 HACER SI i == j ENTONCES matriz[i][j] = 1 SINO matriz[i][j] = 0 FIN SI FIN PARA FIN PARA FIN PROCEDIMIENTO
Ejercicio 3.01.08 - s Adicionales de Matrices ⭐⭐⭐☆☆¶
Ejercicio 3.01.09 - Verificación de Matriz Simétrica ⭐⭐⭐☆☆¶
Solution to Exercise 2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47#include <assert.h> #include <stdbool.h> #include <stddef.h> bool matriz_es_simetrica(const int *mat, size_t n) { if (mat == NULL || n <= 1) { return true; } for (size_t i = 0; i < n; i++) { for (size_t j = i + 1; j < n; j++) { if (mat[i * n + j] != mat[j * n + i]) { return false; } } } return true; } int main(void) { int simetrica_3x3[9] = { 1, 7, 3, 7, 4, 5, 3, 5, 6 }; assert(matriz_es_simetrica(simetrica_3x3, 3) == true); int asimetrica_2x2[4] = { 1, 2, 3, 4 }; assert(matriz_es_simetrica(asimetrica_2x2, 2) == false); int unitaria[1] = {42}; assert(matriz_es_simetrica(unitaria, 1) == true); assert(matriz_es_simetrica(NULL, 0) == true); return 0; }
Ejercicio 3.01.28 - Transposición In-Place de Matriz Cuadrada ⭐⭐⭐☆☆¶
Solution to Exercise 3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58#include <stdio.h> #include <stddef.h> #include <assert.h> void transponer_matriz_cuadrada(int *mat, size_t n) { if (mat == NULL || n <= 1) { return; } for (size_t i = 0; i < n; i++) { for (size_t j = i + 1; j < n; j++) { size_t idx_ij = i * n + j; size_t idx_ji = j * n + i; int temp = mat[idx_ij]; mat[idx_ij] = mat[idx_ji]; mat[idx_ji] = temp; } } } int main(void) { int m3[9] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; transponer_matriz_cuadrada(m3, 3); int esperado_m3[9] = { 1, 4, 7, 2, 5, 8, 3, 6, 9 }; for (size_t i = 0; i < 9; i++) { assert(m3[i] == esperado_m3[i]); } // Matriz simétrica permanece inmutable int sim[4] = { 1, 5, 5, 9 }; transponer_matriz_cuadrada(sim, 2); assert(sim[0] == 1 && sim[1] == 5 && sim[2] == 5 && sim[3] == 9); // Matriz 1x1 int unitaria[1] = {42}; transponer_matriz_cuadrada(unitaria, 1); assert(unitaria[0] == 42); // Caso nulo transponer_matriz_cuadrada(NULL, 0); return 0; }
Ejercicio 3.01.10 - Suma por Filas y Columnas de una Matriz ⭐⭐☆☆☆¶
(ej_b3_c01_11)=
### Ejercicio 3.01.11 - Elemento "Silla" ⭐⭐☆☆☆
#### Descripción
Encontrar un "punto de silla" en una matriz. Un punto de silla es un elemento
que es simultáneamente el valor mínimo en su fila y el valor máximo en su
columna.
::::{tab-set}
:::{tab-item} Entrada
:sync: tab1
Matriz (3x3):
``` text
[ 1, 2, 3 ]
[ 4, 5, 6 ]
[ 7, 8, 9 ]
```
<!-- text -->
Punto de silla encontrado en (2, 0) con valor 7.<!-- {tab-set} -->
:::{hint} Lógica y Consideraciones
- **Proceso:**
1. Iterar a través de cada fila `i` de la matriz.
2. En cada fila, encontrar el valor mínimo y su índice de columna
`min_col_idx`.
3. Una vez encontrado el candidato (el mínimo de la fila), verificar si
este elemento es también el máximo de su columna (`min_col_idx`).
4. Para ello, iterar a través de la columna `min_col_idx` y comparar el
candidato con todos los demás elementos de esa columna.
5. Si el candidato es el mayor de su columna, se ha encontrado un punto de
silla.
:::
<!-- {hint} Lógica y Consideraciones -->
:::{hint} Lógica y Consideraciones
:class: dropdown
```{code-block} pseudocode
:linenos:
PROCEDIMIENTO encontrar_punto_silla(matriz, filas, cols)
INICIO
PARA i DESDE 0 HASTA filas-1 HACER
// Encontrar el mínimo en la fila i
min_fila = matriz[i][0]
min_col_idx = 0
PARA j DESDE 1 HASTA cols-1 HACER
SI matriz[i][j] < min_fila ENTONCES
min_fila = matriz[i][j]
min_col_idx = j
FIN SI
FIN PARA
// Verificar si es el máximo en su columna
es_max_columna = VERDADERO
PARA k DESDE 0 HASTA filas-1 HACER
SI matriz[k][min_col_idx] > min_fila ENTONCES
es_max_columna = FALSO
SALIR DEL LAZO // break
FIN SI
FIN PARA
SI es_max_columna ENTONCES
ESCRIBIR "Punto de silla en (", i, ", ", min_col_idx, ") con valor ", min_fila
RETORNAR
FIN SI
FIN PARA
ESCRIBIR "No se encontraron puntos de silla."
FIN PROCEDIMIENTO
```
<!-- {code-block} pseudocode -->
:::
<!-- {hint} Lógica y Consideraciones -->
(ej_b3_c01_12)=
## Ejercicio 3.01.12 - s de Matrices Dinámicas ⭐⭐⭐☆☆
(ej_b3_c01_13)=
### Ejercicio 3.01.13 - Crear y llenar matriz dinámica ⭐⭐⭐☆☆
#### Descripción
Escribir una función que solicite al usuario las dimensiones (filas y columnas)
y luego los elementos de una matriz, para finalmente imprimirla.
::::{tab-set}
:::{tab-item} Entrada
:sync: tab1
Se le pedirá al usuario que ingrese el número de filas y columnas, y luego cada
uno de los elementos.
:::
<!-- {tab-item} Entrada -->
:::{tab-item} Salida
:sync: tab2
La matriz ingresada por el usuario, impresa de forma ordenada.
:::
<!-- {tab-item} Salida -->
Lógica y Consideraciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18PROCEDIMIENTO crear_y_llenar_matriz_dinamica() INICIO ESCRIBIR "Ingrese el número de filas: " SIN SALTO DE LÍNEA LEER filas ESCRIBIR "Ingrese el número de columnas: " SIN SALTO DE LÍNEA LEER columnas // Crear una matriz de 'filas' x 'columnas' CREAR matriz[filas][columnas] ESCRIBIR "Ingrese los elementos de la matriz:" PARA i DESDE 0 HASTA filas-1 HACER PARA j DESDE 0 HASTA columnas-1 HACER ESCRIBIR "Elemento [", i, "][ ", j, "]: " SIN SALTO DE LÍNEA LEER matriz[i][j] FIN PARA FIN PARA // Asumiendo que la función mostrar_matriz está definida mostrar_matriz(matriz, filas, columnas) FIN PROCEDIMIENTO
Más Algoritmos con Matrices¶
Ejercicio 3.01.14 - Reflejar matriz ⭐⭐⭐☆☆¶
Implementar dos funciones: una que refleje una matriz horizontalmente (la primera fila se intercambia con la última, la segunda con la penúltima, etc.) y otra que la refleje verticalmente (la primera columna con la última, etc.).
Ejercicio 3.01.15 - Intercambiar filas o columnas ⭐⭐☆☆☆¶
Crear funciones intercambiar_filas(mat, f1, f2) e intercambiar_columnas(mat, c1, c2) que modifiquen la matriz intercambiando los elementos de las filas o
columnas especificadas.
Ejercicio 3.01.16 - Búsqueda de submatriz ⭐⭐⭐☆☆¶
Escribir una función que determine si una matriz pequeña B (de k x l) se
encuentra dentro de una matriz más grande A (de m x n). La función debe
devolver las coordenadas de la esquina superior izquierda de la primera
ocurrencia, o (-1, -1) si no se encuentra.
Ejercicio 3.01.17 - Determinante de matriz 3x3 ⭐⭐⭐☆☆¶
Calcular el determinante de una matriz 3x3 utilizando la Regla de Sarrus.
Ejercicio 3.01.18 - Suavizado de matriz (Filtro de caja) ⭐⭐⭐☆☆¶
Implementar un filtro de “suavizado” o “blur”. Para cada elemento de la matriz, su nuevo valor será el promedio de sus 8 vecinos y él mismo. Los elementos en los bordes requerirán un manejo especial.
Ejercicio 3.01.19 - Detección de bordes (Operador de Sobel) ⭐⭐☆☆☆¶
Aplicar un operador de Sobel simple para la detección de bordes. Esto implica
“convolucionar” la matriz con un kernel (otra matriz pequeña, ej. 3x3) para
resaltar las diferencias de intensidad, como los bordes.
Ejercicio 3.01.20 - Matriz de permutación ⭐⭐⭐☆☆¶
Verificar si una matriz cuadrada es una matriz de permutación. Esta es una
matriz binaria (solo 0s y 1s) que tiene exactamente un 1 en cada fila y en
cada columna.
Ejercicio 3.01.21 - Producto de Hadamard ⭐⭐☆☆☆¶
Implementar el producto de Hadamard (o producto elemento a elemento) de dos
matrices A y B de las mismas dimensiones. La matriz resultante C se define
como .
Ejercicio 3.01.22 - Rellenar con triángulo de Pascal ⭐⭐☆☆☆¶
Escribir una función que llene una matriz N x N con los valores del Triángulo
de Pascal. El elemento (i, j) debe ser .
Ejercicio 3.01.23 - Matriz antisimétrica ⭐⭐⭐☆☆¶
Verificar si una matriz cuadrada es antisimétrica. Una matriz A es
antisimétrica si su transpuesta es igual a su negativa, es decir, .
Esto implica que y que todos los elementos de la diagonal
principal deben ser cero.
Operaciones Avanzadas con Matrices¶
Ejercicio 3.01.24 - Norma de matriz ⭐⭐⭐☆☆¶
Implementar funciones que calculen diferentes normas de una matriz.
double norma_frobenius(double **matriz, int filas, int cols);
double norma_maxima(double **matriz, int filas, int cols);
double norma_uno(double **matriz, int filas, int cols);Norma de Frobenius:
Norma máxima: (máxima suma de fila)
Norma uno: (máxima suma de columna)
Ejercicio 3.01.25 - Traza de matriz ⭐⭐⭐☆☆¶
Calcular la traza de una matriz cuadrada (suma de elementos de la diagonal principal).
double traza(double **matriz, int n);Ejercicio 3.01.26 - Rango de matriz ⭐⭐⭐☆☆¶
Implementar un algoritmo para calcular el rango de una matriz usando eliminación gaussiana.
int calcular_rango(double **matriz, int filas, int cols);Estrategia: Reducir la matriz a forma escalonada y contar filas no nulas.
Ejercicio 3.01.27 - Matriz de cofactores ⭐⭐⭐☆☆¶
Calcular la matriz de cofactores para una matriz cuadrada.
double **matriz_cofactores(double **matriz, int n);El cofactor se calcula como: donde es el menor de la matriz (determinante de la submatriz obtenida eliminando fila y columna ).
Ejercicio 3.01.28 - Matriz inversa ⭐⭐⭐☆☆¶
Implementar el cálculo de la inversa de una matriz usando el método de Gauss-Jordan.
double **matriz_inversa(double **matriz, int n, bool *invertible);Algoritmo:
Crear matriz aumentada
Aplicar eliminación Gauss-Jordan
Si se obtiene , retornar
Si no es posible, la matriz no es invertible
Ejercicio 3.01.29 - Potencia de matriz ⭐⭐⭐☆☆¶
Calcular para una matriz cuadrada y un exponente entero .
double **potencia_matriz(double **matriz, int tam, int exponente);Optimización: Usar exponenciación rápida para multiplicaciones.
Ejercicio 3.01.30 - Descomposición LU ⭐⭐☆☆☆¶
Implementar la descomposición LU de una matriz: donde es triangular inferior y es triangular superior.
bool descomposicion_lu(double **A, int n, double **L, double **U);Aplicación: Resolver sistemas de ecuaciones lineales eficientemente.
Ejercicio 3.01.31 - Valores propios (Power Method) ⭐⭐☆☆☆¶
Implementar el método de la potencia para calcular el valor propio dominante de una matriz.
double valor_propio_dominante(double **matriz, int n, double tolerancia);Algoritmo:
Comenzar con vector aleatorio
Iterar:
El valor propio es
Ejercicio 3.01.32 - Matriz de rotación ⭐⭐⭐☆☆¶
Implementar funciones para crear y aplicar matrices de rotación 2D y 3D.
double **matriz_rotacion_2d(double angulo);
double **matriz_rotacion_3d_x(double angulo);
double **matriz_rotacion_3d_y(double angulo);
double **matriz_rotacion_3d_z(double angulo);Matriz de rotación 2D:
Ejercicio 3.01.33 - Matriz de proyección ⭐⭐⭐☆☆¶
Crear matriz de proyección ortogonal sobre un vector.
double **matriz_proyeccion(double *vector, int n);Fórmula:
Algoritmos de Procesamiento de Imágenes¶
Considerar una matriz como una imagen en escala de grises donde cada elemento representa la intensidad de un píxel.
Ejercicio 3.01.34 - Umbralización (Thresholding) ⭐⭐☆☆☆¶
Convertir una imagen en escala de grises a binaria (solo 0 y 255) usando un umbral.
void umbralizar(int **imagen, int filas, int cols, int umbral);Algoritmo: Si pixel >= umbral, asignar 255, sino asignar 0.
Ejercicio 3.01.35 - Histograma de Imagen ⭐⭐☆☆☆¶
Calcular el histograma de una imagen (frecuencia de cada nivel de intensidad).
void calcular_histograma(int **imagen, int filas, int cols, int *histograma);El histograma tiene 256 posiciones (0-255) que cuentan la frecuencia de cada intensidad.
Ejercicio 3.01.36 - Ecualización de Histograma ⭐⭐☆☆☆¶
Mejorar el contraste de una imagen mediante ecualización de histograma.
void ecualizar_histograma(int **imagen, int filas, int cols);Algoritmo:
Calcular histograma
Calcular función de distribución acumulativa (CDF)
Normalizar CDF y aplicar transformación a cada píxel
Ejercicio 3.01.37 - Filtro gaussiano ⭐⭐☆☆☆¶
Implementar un filtro gaussiano para suavizado de imagen.
void filtro_gaussiano(double **imagen, int filas, int cols, double sigma);Kernel gaussiano 3x3:
Ejercicio 3.01.38 - Detección de bordes (Laplaciano) ⭐⭐☆☆☆¶
Aplicar el operador Laplaciano para detectar bordes.
void detectar_bordes_laplaciano(int **imagen, int filas, int cols,
int **resultado);Kernel Laplaciano:
Matrices Especiales¶
Ejercicio 3.01.39 - Matriz de Vandermonde ⭐⭐⭐☆☆¶
Generar una matriz de Vandermonde a partir de un vector.
double **matriz_vandermonde(double *x, int n, int m);Definición:
Ejemplo con y :
Ejercicio 3.01.40 - Matriz de Hilbert ⭐⭐⭐☆☆¶
Generar una matriz de Hilbert de orden .
double **matriz_hilbert(int n);Definición:
Nota: Las matrices de Hilbert son notoriamente mal condicionadas para inversión.
Ejercicio 3.01.41 - Matriz de Toeplitz ⭐⭐⭐☆☆¶
Verificar si una matriz es de Toeplitz (cada diagonal descendente de izquierda a derecha tiene valores constantes).
bool es_toeplitz(int **matriz, int filas, int cols);Propiedad:
Ejercicio 3.01.42 - Matriz circulante ⭐⭐⭐☆☆¶
Generar una matriz circulante a partir de su primera fila.
int **matriz_circulante(int *primera_fila, int n);Ejemplo con primera fila :
Ejercicio 3.01.43 - Matriz de Hankel ⭐⭐⭐☆☆¶
Generar una matriz de Hankel (opuesta a Toeplitz: diagonales de arriba-derecha a abajo-izquierda son constantes).
double **matriz_hankel(double *c, double *r, int n);Resolución de Sistemas de Ecuaciones¶
Ejercicio 3.01.44 - Sustitución hacia adelante ⭐⭐☆☆☆¶
Resolver un sistema triangular inferior .
double *sustitucion_adelante(double **L, double *b, int n);Algoritmo: Resolver de arriba hacia abajo.
Ejercicio 3.01.45 - Sustitución hacia atrás ⭐⭐☆☆☆¶
Resolver un sistema triangular superior .
double *sustitucion_atras(double **U, double *b, int n);Algoritmo: Resolver de abajo hacia arriba.
Ejercicio 3.01.46 - Eliminación gaussiana completa ⭐⭐☆☆☆¶
Implementar eliminación gaussiana con pivoteo completo para resolver .
double *resolver_sistema(double **A, double *b, int n);Ejercicio 3.01.47 - Método de Jacobi ⭐⭐☆☆☆¶
Resolver iterativamente usando el método de Jacobi.
double *metodo_jacobi(double **A, double *b, int n, double tolerancia,
int max_iter);Fórmula de iteración:
Ejercicio 3.01.48 - Método de Gauss-Seidel ⭐⭐☆☆☆¶
Similar a Jacobi pero usa valores actualizados inmediatamente.
double *metodo_gauss_seidel(double **A, double *b, int n, double tolerancia,
int max_iter);Converge más rápido que Jacobi para matrices con diagonal dominante.
Operaciones Matriciales con Bloques¶
Ejercicio 3.01.49 - Multiplicación por bloques ⭐⭐☆☆☆¶
Implementar multiplicación de matrices usando el algoritmo por bloques (más eficiente para matrices grandes por mejor uso de caché).
double **multiplicar_bloques(double **A, double **B, int n, int tam_bloque);Ejercicio 3.01.50 - Transpuesta por bloques ⭐⭐☆☆☆¶
Implementar transpuesta usando bloques para mejor localidad de caché.
void transponer_bloques(double **matriz, int n, int tam_bloque);Ejercicio 3.01.51 - Strassen para matrices grandes ⭐⭐⭐☆☆¶
Implementar el algoritmo de Strassen para multiplicación rápida de matrices grandes.
double **strassen(double **A, double **B, int n);Complejidad: vs del método tradicional.
Ejercicio 3.01.52 - Inicializar y Mostrar Matriz ⭐☆☆☆☆¶
Creá una matriz 3×3, inicializala con valores del 1 al 9, y mostrala.
Orientación:
int matriz[3][3];Lazos anidados para llenar:
matriz[i][j] = contador++Lazos anidados para mostrar con formato
Ejercicio 3.01.53 - Suma de Elementos ⭐☆☆☆☆¶
Calculá la suma de todos los elementos de una matriz.
Orientación:
Recorré con lazos anidados
Acumulá suma en variable
suma += matriz[i][j]
Ejercicio 3.01.54 - Máximo y Mínimo ⭐⭐☆☆☆¶
Encontrá el elemento mayor y menor de una matriz, junto con sus posiciones.
Orientación:
Inicializá
maxyminconmatriz[0][0]Recorré comparando
Guardá posiciones (i, j) cuando actualizás max/min
Ejercicio 3.01.55 - Matriz Identidad ⭐⭐☆☆☆¶
Generá una matriz identidad de tamaño N×N (1s en diagonal, 0s en el resto).
Orientación:
matriz[i][j] = (i == j) ? 1 : 0;O con
if:matriz[i][j] = 1sii == j, sino 0
Ejercicio 3.01.56 - Transpuesta ⭐⭐⭐☆☆¶
Calculá la transpuesta de una matriz (intercambiar filas por columnas).
Orientación:
Matriz original: M×N
Transpuesta: N×M
transpuesta[j][i] = original[i][j]Creá nueva matriz para el resultado
Ejercicio 3.01.57 - Diagonal Principal ⭐⭐☆☆☆¶
Mostrá y sumá los elementos de la diagonal principal de una matriz cuadrada.
Orientación:
Diagonal principal: elementos donde
i == jLazo de 0 a N-1:
suma += matriz[i][i]
Ejercicio 3.01.58 - Diagonal Secundaria ⭐⭐☆☆☆¶
Mostrá y sumá los elementos de la diagonal secundaria.
Orientación:
Diagonal secundaria: elementos donde
i + j == N - 1O directamente:
matriz[i][N-1-i]para i de 0 a N-1
Ejercicio 3.01.59 - Matriz Simétrica ⭐⭐⭐☆☆¶
Verificá si una matriz es simétrica (igual a su transpuesta).
Orientación:
Matriz simétrica:
matriz[i][j] == matriz[j][i]para todo i, jSolo necesitás verificar una mitad (triángulo superior vs inferior)
Si encontrás diferencia,
return falseinmediatamente
Ejercicio 3.01.60 - Suma de Matrices ⭐⭐⭐☆☆¶
Sumá dos matrices del mismo tamaño.
Orientación:
Verificá que tengan las mismas dimensiones
resultado[i][j] = A[i][j] + B[i][j]Creá matriz resultado
Ejercicio 3.01.61 - Multiplicación por Escalar ⭐⭐⭐☆☆¶
Multiplicá todos los elementos de una matriz por un escalar.
Orientación:
Leé el escalar
resultado[i][j] = matriz[i][j] * escalarPodés modificar in-place o crear nueva matriz
Ejercicio 3.01.62 - Buscar Elemento ⭐⭐⭐☆☆¶
Buscá un valor en la matriz. Si lo encontrás, mostrá su posición (fila, columna).
Orientación:
Recorré con lazos anidados
Al encontrar: guardá posición,
breakdel lazo internoUsá flag para
breakdel lazo externo también
Ejercicio 3.01.63 - Suma por Filas y Columnas ⭐⭐⭐☆☆¶
Calculá la suma de cada fila y la suma de cada columna.
Orientación:
Array para sumas de filas:
suma_filas[M]Array para sumas de columnas:
suma_cols[N]Lazo por filas: suma cada fila
Lazo por columnas: suma cada columna
Ejercicio 3.01.64 - Borde de la Matriz ⭐⭐⭐☆☆¶
Mostrá solo los elementos del borde de una matriz.
Orientación:
Primera fila completa:
i == 0Última fila completa:
i == M-1Primera columna:
j == 0Última columna:
j == N-1Usá condición:
if (i == 0 || i == M-1 || j == 0 || j == N-1)
Ejercicio 3.01.65 - Rotar Matriz 90 Grados ⭐⭐⭐⭐☆¶
Rotá una matriz cuadrada 90° en sentido horario.
Orientación:
Para matriz N×N:
Transponer primero:
temp[j][i] = matriz[i][j]Luego invertir cada fila:
resultado[i][j] = temp[i][N-1-j]O directamente:
resultado[j][N-1-i] = matriz[i][j]
Ejercicio 3.01.66 - Multiplicación de Matrices ⭐⭐⭐⭐⭐¶
Multiplicá dos matrices (A de M×N y B de N×P, resultado M×P).
Algoritmo:
C[i][j] = suma de A[i][k] * B[k][j] para k = 0..N-1Orientación:
Tres lazos anidados:
i: filas de A
j: columnas de B
k: suma de productos
Verificá dimensiones compatibles (columnas de A = filas de B)
Ejercicio 3.01.67 - Matriz en Espiral ⭐⭐⭐⭐⭐¶
Llenó una matriz en forma de espiral (desde afuera hacia adentro).
Ejemplo 4×4:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7Orientación:
Usá cuatro límites: arriba, abajo, izquierda, derecha
Recorré en orden: derecha, abajo, izquierda, arriba
Ajustá límites después de cada lado
Repetí hasta llenar todos los elementos
Ejercicio 3.01.68 - Sudoku - Validador de Fila ⭐⭐⭐⭐☆¶
Verificá si una fila de un Sudoku es válida (números 1-9 sin repetir).
Orientación:
Array booleano
visto[10](índices 1-9)Recorré la fila
Si
visto[numero]es true: número repetido, inválidoMarca
visto[numero] = trueAl final, todos los 1-9 deben estar vistos
Ejercicio 3.01.69 - Matriz Traspuesta In-Place ⭐⭐⭐⭐☆¶
Transponé una matriz cuadrada sin usar matriz auxiliar completa.
Orientación:
Solo intercambiá elementos por encima de la diagonal
for (i = 0; i < N; i++)for (j = i+1; j < N; j++)Intercambiá
matriz[i][j]conmatriz[j][i]
Ejercicio 3.01.70 - Matriz de Distancias ⭐⭐⭐⭐⭐¶
Dadas N ciudades con coordenadas (x, y), calculá matriz de distancias entre todas.
Orientación:
Matriz de distancias D[i][j] = distancia de ciudad i a ciudad j
Distancia euclidiana:
sqrt((x2-x1)² + (y2-y1)²)Diagonal es 0 (distancia de ciudad a sí misma)
Matriz es simétrica:
D[i][j] = D[j][i]
Ejercicio 3.01.71 - Juego de la Vida (Conway) ⭐⭐⭐⭐⭐¶
Implementá una generación del Juego de la Vida de Conway.
Reglas:
Celda viva con 2-3 vecinos vivos: sobrevive
Celda muerta con exactamente 3 vecinos vivos: nace
Otras: muere o permanece muerta
Orientación:
Matriz actual y matriz siguiente
Función para contar vecinos vivos (8 direcciones)
Aplicá reglas para cada celda
Copiá matriz siguiente a actual para próxima generación
Vecinos: (i-1,j-1), (i-1,j), (i-1,j+1), (i,j-1), (i,j+1), (i+1,j-1), (i+1,j), (i+1,j+1)
Cuidado con bordes
Ejercicio 3.01.72 - s Adicionales ⭐⭐☆☆☆¶
Ejercicio 3.01.73 - Matriz Pascal (Triángulo de Pascal) ⭐⭐⭐⭐☆¶
Generá el triángulo de Pascal como matriz.
Orientación:
matriz[i][0] = 1(primera columna)matriz[i][i] = 1(diagonal)matriz[i][j] = matriz[i-1][j-1] + matriz[i-1][j](resto)
Ejercicio 3.01.74 - Matriz Antisimétrica ⭐⭐⭐⭐☆¶
Verificá si una matriz es antisimétrica (A[i][j] = -A[j][i]).
Orientación:
Diagonal debe ser cero:
A[i][i] = 0Verificá:
matriz[i][j] == -matriz[j][i]
Ejercicio 3.01.75 - Submatriz Mayor Suma ⭐⭐⭐⭐⭐¶
Encontrá la submatriz 2×2 con mayor suma dentro de una matriz más grande.
Orientación:
Recorré todas las posiciones posibles para submatriz 2×2
Para cada posición, sumá los 4 elementos
Guardá máximo y posición
Ejercicio 3.01.76 - Matriz Dispersa (Sparse) ⭐⭐⭐⭐⭐¶
Representá una matriz dispersa (muchos ceros) eficientemente.
Orientación:
Estructura:
{fila, columna, valor}solo para elementos != 0Array de estructuras
Funciones:
asignar(f, c, val),obtener(f, c),mostrar()
Notas Finales¶
Estas consignas cubren arrays bidimensionales desde operaciones básicas hasta algoritmos complejos, preparando para trabajar con matrices dinámicas en apuntes posteriores.