Tengo un número entero N. Tengo que encontrar el número entero más pequeño mayor que N que no contenga ningún dígito que no sea 0 o 1. Por ejemplo: si N = 12
entonces la respuesta es 100
. He codificado un enfoque de fuerza bruta en C ++.
int main() {
long long n;
cin >> n;
for (long long i = n + 1; ; i++) {
long long temp = i;
bool ok = true;
while (temp != 0) {
if ( (temp % 10) != 0 && (temp % 10) != 1) {
ok = false;
break;
}
temp /= 10;
}
if (ok == true) {
cout << i << endl;
break;
}
}
}
El problema es que mi enfoque es demasiado lento. Creo que hay un enfoque muy eficiente para resolver esto. ¿Cómo puedo resolver este problema de manera eficiente?
N
permite negativo ? Además, esto es difícil ya que corre el riesgo de desbordar su tipo. ¿Cuáles son los límitesN
?Respuestas:
Incremento N,
Comenzando desde la izquierda, escanee hasta que encuentre un dígito arriba 1. Incremente el número parcial antes y ponga a cero el resto.
P.ej
Prueba:
El número solicitado debe ser al menos N + 1, es por eso que incrementamos. Ahora estamos buscando un número mayor o igual.
Llamemos al prefijo los dígitos iniciales 0/1 y el sufijo que sigue. Debemos reemplazar el primer dígito del sufijo por un cero y establecer un prefijo más grande. El prefijo más pequeño que se ajusta es el prefijo actual más uno. Y el sufijo más pequeño que cabe es todos ceros.
Actualizar:
Olvidé especificar que el prefijo debe incrementarse como un número binario ; de lo contrario, podrían aparecer dígitos prohibidos.
fuente
Otra posibilidad sería la siguiente:
Comienza con el número decimal más grande del tipo "1111111 ... 1111" admitido por el tipo de datos utilizado
El algoritmo supone que la entrada es menor que este número; de lo contrario, tendrá que usar otro tipo de datos.
Ejemplo: al usar
long long
, comienza con el número1111111111111111111
.Ejemplo
Prueba de corrección:
Procesamos dígito a dígito en este algoritmo. En cada paso, hay dígitos cuyo valor ya se conoce y dígitos cuyos valores aún no se conocen.
En cada paso, exploramos el dígito desconocido más a la izquierda.
Establecemos ese dígito en "0" y todos los demás dígitos desconocidos en "1". Debido a que el dígito a sondear es el más significativo de los dígitos desconocidos, el número resultante es el número más grande posible con ese dígito siendo un "0". Si este número es menor o igual a la entrada, el dígito que se está probando debe ser un "1".
Por otro lado, el número resultante es más pequeño que todos los números posibles donde el dígito que se está probando es un "1". Si el número resultante es mayor que la entrada, el dígito debe ser "0".
Esto significa que podemos calcular un dígito en cada paso.
Código C
(El código C también debería funcionar en C ++):
fuente
Déjame sugerirte un par de alternativas.
I. Incrementando. Considérelo una modificación del método @YvesDaoust.
(a) si es menor que 2, luego deje todo como está
(b) de lo contrario, ajústelo a 0 y aumente
Ejemplos:
Obtiene el resultado en formato decimal.
II Divisor.
(a) si M excede 1, luego aumente D
(b) o aumente la suma en M * 10 k , donde k es el número de iteración actual (comenzando con 0)
Ejemplo 1:
Ejemplo 2
Ejemplo 3
Ejemplo 4
fuente