Medio · arrays 2D
Transponer una matriz
Ya sabes sumar una matriz. Transponerla plantea una pregunta más afilada: cuando escribes a[i][j], ¿seguro que sabes qué significa cada índice?
En una fraseImprime la columna j de la entrada como fila j de la salida: los bucles se intercambian, con el externo sobre columnas y el interno sobre filas.
El problema
Entrada: La primera línea tiene dos enteros n y m (1 ≤ n, m ≤ 50): filas y columnas. Las siguientes n líneas tienen m enteros cada una.
Salida: La traspuesta: m líneas con n enteros cada una. La fila j de la salida es la columna j de la entrada.
Ejemplos:
| Entrada | Salida |
|---|---|
2 3 | 1 4 |
1 1 | 7 |
3 1 | 1 2 3 |
Fíjate en que la forma cambia: una matriz 2×3 pasa a ser 3×2. Así que los dos bucles que imprimen la respuesta tienen los límites intercambiados: ese es todo el truco y toda la trampa.
Tu solución
Entrada personalizada para «Ejecutar mi entrada»
La corrección corre en tu navegador contra pruebas ocultas. Un bucle infinito se corta a los 3 segundos — aun así, asegúrate de que todo bucle tenga salida. Tu código se guarda solo mientras escribes.
¿Atascado? Pistas
Pista 1 — No necesitas un segundo array
Lo obvio es construir b[m][n] con b[j][i] = a[i][j] y luego imprimirlo. Funciona, pero puedes imprimir directamente: leer la matriz por filas e imprimirla por columnas es la traspuesta. Un array, cero copias.
Pista 2 — Intercambia los límites, no solo los índices
El bucle externo lleva j de 0 a m - 1, el interno lleva i de 0 a n - 1. Escribir a[j][i] manteniendo los límites en n y m se sale del array en cuanto la matriz no es cuadrada, y si es cuadrada imprime la original en silencio.
Pista 3 — Di los índices en voz alta
a[fila][columna]: el primer índice es siempre la fila, en C++ y en cualquier lenguaje con esta notación. Antes de escribir un bucle anidado sobre una rejilla, di qué variable es la fila y cuál la columna. Casi todos los bugs de arrays 2D no son de lógica, sino un intercambio que no notaste.
Solución (¡inténtalo primero!)
#include <iostream>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
int a[55][55];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> a[i][j];
for (int j = 0; j < m; j++) {
for (int i = 0; i < n; i++) {
cout << a[i][j] << " ";
}
cout << endl;
}
return 0;
}
Transponer sin un segundo array funciona porque nunca necesitaste que la traspuesta existiera: solo necesitabas leer los datos en otro orden. Esa distinción, "¿necesito reordenar los datos o solo recorrerlos distinto?", te ahorra una copia en muchos problemas. Girar una matriz 90°, multiplicar dos matrices y recorrer las diagonales de una rejilla son variaciones de esto. Ahora, un problema donde el dato es un número escrito en la base que tú elijas: Conversión de base.
Análisis profundo
Por qué funciona
Leer la matriz por filas e imprimirla por columnas <em>es</em> la traspuesta. Nunca necesitaste que existiera: solo recorrerla de otra forma.
El coste
O(n×m) de tiempo y cero espacio extra. Construir una segunda matriz y imprimirla cuesta un bloque n×m para nada.
Dónde falla
- Cambiar a
a[j][i]manteniendo los límites ennymse sale del array en cuanto la matriz no es cuadrada, y si es cuadrada imprime la original en silencio. - En
a[fila][columna]el primer índice es siempre la fila. Di en voz alta qué variable es cuál antes de escribir un bucle anidado sobre una rejilla.
Siguiente paso
Ahora el dato es un número escrito en la base que elijas: Conversión de base.
Dos cosas para recordar
- Leer por filas, imprimir por columnas: esa es la traspuesta.
a[fila][columna]: el primer índice es siempre la fila.
🐞 Esta versión falla: ábrela y pruébala
Imprime la matriz tal cual: la traspuesta nunca ocurrió
#include <iostream>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
int a[55][55];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> a[i][j];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) cout << a[i][j] << " ";
cout << endl;
}
return 0;
}