J'ai un entier N. Je dois trouver le plus petit entier supérieur à N qui ne contient aucun chiffre autre que 0 ou 1. Par exemple: Si N = 12
alors la réponse est 100
. J'ai codé une approche par force brute 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;
}
}
}
Le problème est que mon approche est trop lente. Je pense qu'il existe une approche très efficace pour résoudre ce problème. Comment puis-je résoudre ce problème efficacement?
N
autorisé? En outre, cela est difficile car vous risquez de déborder votre type. Quelles sont les limitesN
?Réponses:
Incrément N,
En partant de la gauche, scannez jusqu'à ce que vous trouviez un chiffre au-dessus de 1. Incrémentez le nombre partiel avant lui et mettez à zéro le reste.
Par exemple
Preuve:
Le nombre demandé doit être au moins N + 1, c'est pourquoi nous incrémentons. Nous recherchons maintenant un nombre supérieur ou égal.
Appelons le préfixe les premiers chiffres 0/1 et le suffixe ce qui vient après. Nous devons remplacer le premier chiffre du suffixe par un zéro et définir un préfixe plus grand. Le plus petit préfixe qui convient est le préfixe actuel plus un. Et le plus petit suffixe qui convient est tous les zéros.
Mise à jour:
J'ai oublié de préciser que le préfixe doit être incrémenté sous forme de nombre binaire , sinon des chiffres interdits pourraient apparaître.
la source
Une autre possibilité serait la suivante:
Vous commencez avec le plus grand nombre décimal du type "1111111 ... 1111" pris en charge par le type de données utilisé
L'algorithme suppose que l'entrée est inférieure à ce nombre; sinon, vous devrez utiliser un autre type de données.
Exemple: lorsque vous utilisez
long long
, vous commencez par le nombre1111111111111111111
.Exemple
Preuve de correction:
Nous traitons chiffre par chiffre dans cet algorithme. À chaque étape, il y a des chiffres dont la valeur est déjà connue et des chiffres dont les valeurs ne sont pas encore connues.
À chaque étape, nous sondons le chiffre inconnu le plus à gauche.
Nous avons mis ce chiffre à "0" et tous les autres chiffres inconnus à "1". Étant donné que le chiffre à sonder est le plus important des chiffres inconnus, le nombre résultant est le plus grand nombre possible, ce chiffre étant un "0". Si ce nombre est inférieur ou égal à l'entrée, le chiffre sondé doit être un "1".
D'un autre côté, le nombre résultant est plus petit que tous les nombres possibles où le chiffre sondé est un "1". Si le nombre résultant est supérieur à l'entrée, le chiffre doit être "0".
Cela signifie que nous pouvons calculer un chiffre à chaque étape.
Code C
(Le code C devrait également fonctionner sous C ++):
la source
Permettez-moi de suggérer quelques alternatives.
I. Incrémentation. Considérez cela comme une modification de la méthode @YvesDaoust.
(a) s'il est inférieur à 2, puis laissez tout tel
quel (b) sinon mettez-le à 0 et augmentez le précédent
Exemples:
Vous obtenez le résultat au format décimal.
II. Partage.
(a) si M dépasse 1 puis augmentez D
(b) sinon augmentez la somme de M * 10 k , où k est le numéro d'itération actuel (commençant par 0)
Exemple 1:
Exemple 2:
Exemple 3:
Exemple 4:
la source