Mam liczbę całkowitą N. Muszę znaleźć najmniejszą liczbę całkowitą większą niż N, która nie zawiera żadnej cyfry innej niż 0 lub 1. Na przykład: Jeśli tak, N = 12
to odpowiedź brzmi 100
. W C ++ zakodowałem podejście z użyciem siły brutalnej.
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;
}
}
}
Problem polega na tym, że moje podejście jest zbyt wolne. Uważam, że istnieje bardzo skuteczne podejście do rozwiązania tego. Jak mogę skutecznie rozwiązać ten problem?
N
dozwolone jest negatywne ? Jest to również trudne, ponieważ ryzykujesz przepełnienie swojego typu. Jakie są graniceN
?Odpowiedzi:
Przyrost N,
Zaczynając od lewej, skanuj, aż znajdziesz cyfrę powyżej 1. Zwiększ liczbę częściową przed nią i wyzeruj resztę.
Na przykład
Dowód:
Wymagana liczba musi wynosić co najmniej N + 1, dlatego zwiększamy. Szukamy teraz liczby większej lub równej.
Nazwijmy prefiks początkowymi cyframi 0/1 i sufiksem, co nastąpi później. Musimy zamienić pierwszą cyfrę sufiksu na zero i ustawić większy prefiks. Najmniejszy przedrostek, który pasuje, to bieżący przedrostek plus jeden. Najmniejszy przyrostek, który pasuje, to wszystkie zera.
Aktualizacja:
Zapomniałem podać, że przedrostek musi być zwiększany jako liczba binarna , w przeciwnym razie mogłyby pojawić się zabronione cyfry.
źródło
Inną możliwością byłaby następująca:
Zaczynasz od największej liczby dziesiętnej typu „1111111 ... 1111” obsługiwanej przez użyty typ danych
Algorytm zakłada, że dane wejściowe są mniejsze niż ta liczba; w przeciwnym razie będziesz musiał użyć innego typu danych.
Przykład: Podczas używania
long long
zaczynasz od numeru1111111111111111111
.Przykład
Dowód poprawności:
W tym algorytmie przetwarzamy cyfra po cyfrze. Na każdym etapie znajdują się cyfry, których wartość jest już znana, i cyfry, których wartości nie są jeszcze znane.
Na każdym kroku badamy najbardziej nieznaną lewą cyfrę.
Ustawiamy tę cyfrę na „0”, a wszystkie inne nieznane cyfry na „1”. Ponieważ cyfra, która ma być sondowana, jest najbardziej znaczącą z nieznanych cyfr, wynikowa liczba jest największą możliwą liczbą, przy czym cyfra ta to „0”. Jeśli liczba ta jest mniejsza lub równa wartości wejściowej, badana cyfra musi być „1”.
Z drugiej strony wynikowa liczba jest mniejsza niż wszystkie możliwe liczby, w których badana cyfra to „1”. Jeśli wynikowa liczba jest większa niż wartość wejściowa, cyfra musi wynosić „0”.
Oznacza to, że możemy obliczyć jedną cyfrę na każdym kroku.
Kod C.
(Kod C powinien również działać w C ++):
źródło
Pozwól, że zasugeruję kilka alternatyw.
I. Zwiększanie. Rozważ to modyfikację metody @YvesDaoust.
(a), jeśli jest mniejsza niż 2, pozostaw wszystko tak, jak jest
(b) w przeciwnym razie ustaw na 0 i zwiększ poprzedzające
Przykłady:
Otrzymasz wynik w formacie dziesiętnym.
II. Działowy.
(a), jeśli M przekracza 1, zwiększ D
(b), w przeciwnym razie zwiększ sumę o M * 10 k , gdzie k jest bieżącą liczbą iteracji (zaczynając od 0)
Przykład 1:
Przykład 2:
Przykład 3:
Przykład 4:
źródło