Medio · sistemas numéricos
Conversión de base
Ya sabes convertir a binario. Lo único que cambia para otras bases es la base, y que a partir de 10 se acaban los caracteres de dígito.
En una fraseToma n % base como siguiente dígito y divide n entre base, y luego imprime los dígitos al revés: los dígitos mayores que 9 pasan a A–F, y 0 se imprime como 0.
El problema
Entrada: Una línea con dos enteros: n (0 ≤ n ≤ 1,000,000) y base (2 ≤ base ≤ 16).
Salida: n escrito en esa base. Los dígitos mayores que 9 son letras mayúsculas A–F. Si n es 0, imprime 0.
Ejemplos:
| Entrada | Salida |
|---|---|
255 16 | FF |
10 2 | 1010 |
0 2 | 0 |
Los restos salen al revés. 10 en base 2 produce los restos 0, 1, 0, 1, que es la respuesta leída al revés. Recógelos y luego imprímelos en orden inverso.
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 — Parte del binario que ya escribiste
En el problema del binario hacías n % 2 y n / 2. Cambia el 2 por base y el algoritmo no cambia: nunca le importó cuál era la base. Ese es el sentido de una solución general.
Pista 2 — Los dígitos mayores que 9 necesitan conversión
El resto es un número 0–15, pero debes guardar un carácter. Para 0–9 es '0' + r; para 10–15, 'A' + (r - 10). Un ternario hace ambos: r < 10 ? '0' + r : 'A' + r - 10.
Pista 3 — El cero es el caso que rompe el bucle
while (n > 0) no se ejecuta ni una vez cuando n es 0, así que no se recoge nada y se imprime una línea vacía. Resuélvelo antes del bucle: si n == 0, imprime 0 y termina. Es el mismo caso límite que hace tropezar a toda rutina de "convertir un número en dígitos".
Solución (¡inténtalo primero!)
#include <iostream>
using namespace std;
int main() {
int n, base;
cin >> n >> base;
if (n == 0) {
cout << 0 << endl;
return 0;
}
char digit[64];
int k = 0;
while (n > 0) {
int r = n % base;
digit[k] = (r < 10) ? ('0' + r) : ('A' + r - 10);
k++;
n = n / base;
}
for (int i = k - 1; i >= 0; i--) cout << digit[i];
cout << endl;
return 0;
}
Los restos de la división repetida, leídos al revés, son los dígitos. Esa sola frase explica a la vez el binario, el octal, el hexadecimal y cualquier sistema posicional: solo cambia la rapidez con que el número se encoge. La dirección inversa (de una cadena en cierta base a un entero) es el mismo bucle al revés, n = n * base + digit, que es literalmente lo que hacen stoi y cin >> por dentro. Ahora, una ordenación en la que nunca comparas nada: Ordenación por conteo.
Análisis profundo
Por qué funciona
Los restos de la división repetida, leídos al revés, son los dígitos. Esa frase explica a la vez todos los sistemas posicionales.
El coste
O(log_base n) divisiones. A mayor base, menos pasos: mil millones son 30 divisiones en binario pero solo 8 en hexadecimal.
Dónde falla
- Olvidar invertir: los restos salen al revés. 10 en binario da 0,1,0,1; impreso en orden eso es
0101. - Faltar el caso
n == 0:while (n > 0)no se ejecuta y se imprime una línea vacía. El cero es0en cualquier base.
Siguiente paso
Una ordenación que no compara nada: Ordenación por conteo.
Dos cosas para recordar
- Lee los restos al revés: binario, octal y hex son esa misma frase.
- Trata el 0 aparte, o imprimirás una línea vacía.
🐞 Esta versión falla: ábrela y pruébala
Restos impresos en el orden en que salieron: los dígitos quedan al revés
#include <iostream>
using namespace std;
int main() {
int n, base;
cin >> n >> base;
if (n == 0) {
cout << 0 << endl;
return 0;
}
char digit[64];
int k = 0;
while (n > 0) {
int r = n % base;
digit[k] = (r < 10) ? ('0' + r) : ('A' + r - 10);
k++;
n = n / base;
}
for (int i = 0; i < k; i++) cout << digit[i];
cout << endl;
return 0;
}