Ich habe eine Ganzzahl N. Ich muss die kleinste Ganzzahl größer als N finden, die keine andere Ziffer als 0 oder 1 enthält. Zum Beispiel: Wenn N = 12
dann die Antwort lautet 100
. Ich habe einen Brute-Force-Ansatz in C ++ codiert.
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;
}
}
}
Das Problem ist, mein Ansatz ist zu langsam. Ich glaube, es gibt einen sehr effizienten Ansatz, um dies zu lösen. Wie kann ich dieses Problem effizient lösen?
N
erlaubt? Dies ist auch schwierig, da Sie Gefahr laufen, Ihren Typ zu überlaufen. Was sind die GrenzenN
?Antworten:
Inkrement N,
Scannen Sie von links, bis Sie eine Ziffer über 1 finden. Erhöhen Sie die Teilzahl davor und setzen Sie den Rest auf Null.
Z.B
Beweis:
Die angeforderte Nummer muss mindestens N + 1 sein, deshalb erhöhen wir. Wir suchen jetzt nach einer größeren oder gleichen Zahl.
Nennen wir das Präfix die ersten 0/1-Ziffern und das Suffix, was danach kommt. Wir müssen die erste Ziffer des Suffix durch eine Null ersetzen und ein größeres Präfix setzen. Das kleinste passende Präfix ist das aktuelle Präfix plus eins. Und das kleinste passende Suffix sind alle Nullen.
Aktualisieren:
Ich habe vergessen anzugeben, dass das Präfix als Binärzahl erhöht werden muss, da sonst verbotene Ziffern auftreten können.
quelle
Eine andere Möglichkeit wäre die folgende:
Sie beginnen mit der größten Dezimalzahl des Typs "1111111 ... 1111", die vom verwendeten Datentyp unterstützt wird
Der Algorithmus geht davon aus, dass die Eingabe kleiner als diese Zahl ist. Andernfalls müssen Sie einen anderen Datentyp verwenden.
Beispiel: Bei der Verwendung
long long
beginnen Sie mit der Nummer1111111111111111111
.Beispiel
Korrektheitsnachweis:
Wir verarbeiten in diesem Algorithmus Ziffer für Ziffer. In jedem Schritt gibt es Ziffern, deren Wert bereits bekannt ist, und Ziffern, deren Werte noch nicht bekannt sind.
In jedem Schritt prüfen wir die am weitesten links stehende unbekannte Ziffer.
Wir setzen diese Ziffer auf "0" und alle anderen unbekannten Ziffern auf "1". Da die zu prüfende Ziffer die höchstwertige der unbekannten Ziffern ist, ist die resultierende Zahl die größtmögliche Zahl, wobei diese Ziffer eine "0" ist. Wenn diese Zahl kleiner oder gleich der Eingabe ist, muss die zu prüfende Ziffer eine "1" sein.
Andererseits ist die resultierende Zahl kleiner als alle möglichen Zahlen, bei denen die zu prüfende Ziffer eine "1" ist. Wenn die resultierende Zahl größer als die Eingabe ist, muss die Ziffer "0" sein.
Dies bedeutet, dass wir in jedem Schritt eine Ziffer berechnen können.
C-Code
(Der C-Code sollte auch unter C ++ funktionieren):
quelle
Lassen Sie mich einige Alternativen vorschlagen.
I. Inkrementieren. Betrachten Sie es als eine Modifikation der @ YvesDaoust-Methode.
(a), wenn sie kleiner als 2 ist, und lassen Sie alles so, wie es ist
(b), andernfalls setzen Sie es auf 0 und erhöhen Sie es vorher
Beispiele:
Sie erhalten das Ergebnis im Dezimalformat.
II. Teilen.
(a), wenn M 1 überschreitet, und erhöhen Sie dann D
(b), andernfalls erhöhen Sie die Summe um M * 10 k , wobei k die aktuelle Iterationszahl ist (beginnend mit 0).
Beispiel 1:
Beispiel 2:
Beispiel 3:
Beispiel 4:
quelle