Dados dos números representados como cadenas y una base (radix) para uno de ellos, el objetivo es encontrar la base para el segundo número de modo que ambos representen el mismo valor decimal. Este desafío requiere evaluar bases numéricas desconocidas usando algoritmos eficeintes.
Implementación en C++ con Búsqueda Binaria
La solución se basa en convertir ambos números a un sistema común, como decimal, y aplicar búsqueda binaria para hallar la base desconocida. A continuación, se presenta el código reestructurado con nombres de variables y lógica modificada.
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
// Convierte una cadena en la base dada a su valor decimal
long long transformarADecimal(const string& numero, long long base) {
long long valor = 0;
for (char simbolo : numero) {
int digito;
if (simbolo >= '0' && simbolo <= '9') {
digito = simbolo - '0';
} else {
digito = simbolo - 'a' + 10;
}
valor = valor * base + digito;
}
return valor;
}
// Calcula la base mínima válida para una cadena numérica
long long obtenerBaseMinima(const string& numero) {
char simboloMax = *max_element(numero.begin(), numero.end());
int valorMax;
if (simboloMax >= '0' && simboloMax <= '9') {
valorMax = simboloMax - '0';
} else {
valorMax = simboloMax - 'a' + 10;
}
return valorMax + 1;
}
// Usa búsqueda binaria para determinar la base que iguala al valor objetivo
long hallarBase(const string& numero, long long objetivo) {
long long limiteInferior = obtenerBaseMinima(numero);
long long limiteSuperior = max(limiteInferior, objetivo + 1);
while (limiteInferior <= limiteSuperior) {
long long puntoMedio = limiteInferior + (limiteSuperior - limiteInferior) / 2;
long long valorConvertido = transformarADecimal(numero, puntoMedio);
if (valorConvertido == objetivo) {
return puntoMedio;
} else if (valorConvertido < 0 || valorConvertido > objetivo) {
limiteSuperior = puntoMedio - 1;
} else {
limiteInferior = puntoMedio + 1;
}
}
return -1;
}
int main() {
string entrada1, entrada2;
int indicador;
long long baseConocida;
cin >> entrada1 >> entrada2 >> indicador >> baseConocida;
string numConocido = (indicador == 1) ? entrada1 : entrada2;
string numDesconocido = (indicador == 1) ? entrada2 : entrada1;
long long valorReferencia = transformarADecimal(numConocido, baseConocida);
long long baseEncontrada = hallarBase(numDesconocido, valorReferencia);
if (baseEncontrada == -1) {
cout << "Imposible" << endl;
} else {
cout << baseEncontrada << endl;
}
return 0;
}
</algorithm></string></iostream>
Consideraciones Técnicas
- La conversión a decimal permite comparar números en bases diferetnes de manera uniforme.
- La búsqueda binaria reduce la complejidad temporal al O(log N) para explorar posibles bases.
- La base mínima se deriva del dígito más alto en la cadena, garantizando consistencia en la representación.
Uso de Funciones Estándar en C++
Función max_element
Esta función de la biblioteca <algorithm> localiza el elemanto máximo en un rango. Se puede usar con contenedores como cadenas o vectores, y admite criterios personalizados mediante lambdas.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> datos = {5, 2, 8, 1, 9};
auto itMax = max_element(datos.begin(), datos.end());
cout << "Valor máximo: " << *itMax << endl;
string texto = "cadabra";
char caracterMax = *max_element(texto.begin(), texto.end());
cout << "Carácter máximo: " << caracterMax << endl;
vector<int> mixto = {-3, 4, -2, 6};
auto itAbsMax = max_element(mixto.begin(), mixto.end(),
[](int a, int b) { return abs(a) < abs(b); });
cout << "Valor absoluto máximo: " << *itAbsMax << endl;
return 0;
}
</int></int></algorithm></vector></iostream>
Algoritmo de Búsqueda Binaria
La búsqueda binaria es ideal para arreglos ordenados o rangos definidos, ofreciendo eficiencia logarítmica. Implementarla correctamente involucra ajustar límites basados en comparaciones intermedias.
#include <vector>
using namespace std;
int busquedaBinaria(const vector<int>& arreglo, int objetivo) {
int izquierda = 0, derecha = arreglo.size() - 1;
while (izquierda <= derecha) {
int medio = izquierda + (derecha - izquierda) / 2;
if (arreglo[medio] == objetivo) {
return medio;
} else if (arreglo[medio] < objetivo) {
izquierda = medio + 1;
} else {
derecha = medio - 1;
}
}
return -1;
}
</int></vector>