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:

EntradaSalida
2 3
1 2 3
4 5 6
1 4
2 5
3 6
1 1
7
7
3 1
1
2
3
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

main.cpp — 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 en n y m se 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;
}