Perfect Number
Dzielnik właściwy liczby n to dodatni dzielnik mniejszy od samej liczby n. Liczba doskonała jest równa sumie swoich dzielników właściwych: 6 = 1 + 2 + 3. Otrzymujesz dodatnią liczbę całkowitą n. Zwróć true, jeśli n jest doskonała, a w przeciwnym razie false.
Funkcja
- ninteger
- testowana dodatnia liczba całkowita
- Zwracaboolean
- true, jeśli n jest równe sumie swoich dzielników właściwych, false w przeciwnym razie
Ograniczenia
1 ≤ n ≤ 108
Przykłady
- Wejście
- n = 28
- Wyjście
- true
- Wyjaśnienie
- Właściwe dzielniki liczby
28to1,2,4,7i14. Ich suma wynosi28, więc28jest liczbą doskonałą.
- Wejście
- n = 12
- Wyjście
- false
- Wyjaśnienie
- Właściwe dzielniki liczby
12to1,2,3,4i6. Ich suma wynosi16, czyli przekracza12.
- Wejście
- n = 1
- Wyjście
- false
- Wyjaśnienie
1nie ma żadnego właściwego dzielnika, więc suma wynosi0, a nie1.
+16 ukrytych testów przy wysłaniu
Pytanie dodatkowe
Każda parzysta liczba doskonała ma postać 2^(p-1) × (2^p-1), gdzie 2^p-1 jest liczbą pierwszą. Czy potrafisz wypisać wszystkie liczby doskonałe mniejsze niż 10^8 za pomocą tego wzoru, bez testowania każdej liczby?
Podpowiedzi
Otwieraj je po kolei. Każda zdradza trochę więcej.
Zapisz dzielniki właściwe liczby
28. Które z nich znajdziesz, jeśli sprawdzisz tylko liczby do5?Dzielniki występują parami: jeśli
ddzielin, ton / drównież. Jeden z elementów każdej pary jest nie większy niż√n.Ustaw wartość całkowitą początkowo na
1, zwracajfalsedlan == 1i iteruj podod2, dopókid * d ≤ n. Dodawajdin / d, ale tylko raz, gdy są sobie równe.
Rozwiązanie
Definicja wymaga sumy dzielników, a oczywista pętla sprawdza każdego kandydata aż do n / 2. Dla n = 10^8 oznacza to 5 × 10^7 dzieleń. Dzielniki występują w parach, których iloczyn wynosi n, więc możesz zebrać oba elementy każdej pary, przeszukując liczby tylko do √n, czyli wykonując około 10^4 kroków.
Dodaj każdy właściwy dzielnik
Poprawne, ale nie kończy się na największych testach
Intuicja
Postępuj zgodnie z definicją. Sprawdź po kolei każdą wartość d, zaczynając od 1, a gdy n % d == 0, dodaj d do sumy bieżącej. Na końcu porównaj sumę z n. Dla 28 pętla uwzględnia 1, 2, 4, 7 i 14, a 1 + 2 + 4 + 7 + 14 = 28.
Możesz zakończyć na n / 2. Dzielnik inny niż n pozostawia iloraz wynoszący co najmniej 2, więc nigdy nie jest większy niż połowa n. To ograniczenie działa także dla n = 1: pętla wykonuje się zero razy, suma pozostaje równa 0, a odpowiedzią jest false.
Podzielenie zakresu na pół nie zmienia tempa wzrostu. Dla n = 10^8 pętla nadal wykonuje się 5 × 10^7 razy, i dzieje się tak dla każdego wejścia o takim rozmiarze, niezależnie od tego, czy jest dzielnikiem.
Algorytm
- Ustaw
totalna0. - Przejdź pętlą przez
dod1don / 2. - Jeśli
n % d == 0, dodajddototal. - Zwróć informację, czy
total == n.
def isPerfect(n):
total = 0
# No proper divisor of n is larger than n / 2.
for d in range(1, n // 2 + 1):
if n % d == 0:
total += d
return total == nZbieraj pary dzielników do pierwiastka kwadratowego
Intuicja
Gdy d dzieli n, to n / d również je dzieli. Dla 28 pary to 1 × 28, 2 × 14 i 4 × 7. W każdej parze jeden element jest nie większy niż √n, ponieważ iloczyn dwóch liczb większych od √n jest większy niż n. Wystarczy więc przeszukać liczby do √n, aby znaleźć każdą parę dokładnie raz, i dodawać oba jej elementy.
Na dwa elementy trzeba uważać. Para 1 × n zawiera samo n, które nie jest właściwym dzielnikiem: zacznij sumę od 1, a przeszukiwanie od 2. Ten początek jest nieprawidłowy dla n = 1, którego jedynym dzielnikiem jest ono samo, więc najpierw zwróć dla niego false. A gdy n jest kwadratem, pierwiastek tworzy parę z samym sobą: dla 36 para 6 × 6 powinna dodać 6 raz, a nie dwa razy.
Zapisz ograniczenie jako d * d ≤ n, dzięki czemu pozostajesz w liczbach całkowitych. Dla n = 10^8 pętla kończy się przy d = 10^4, więc wykonuje około 10^4 iteracji zamiast 5 × 10^7.
Algorytm
- Jeśli
n == 1, zwróćfalse. - Ustaw
totalna1, adna2. - Gdy
d * d ≤ n: jeślidjest dzielnikiemn, dodajd, a takżen / d, jeśli różni się odd. - Przejdź do następnej wartości
d. - Zwróć informację, czy
total == n.
def isPerfect(n):
if n == 1:
return False
total = 1 # 1 divides every n > 1; n itself does not count
d = 2
while d * d <= n:
if n % d == 0:
total += d
partner = n // d
if partner != d: # a square root pairs with itself: add it once
total += partner
d += 1
return total == n
Pułapki i przypadki brzegowe
Sztuczka z parami jest krótka, a każdy z jej błędów zmienia sumę dokładnie o jeden dzielnik.
- Liczenie samego
n. Para1 × ndodajen, przez co każda liczba wygląda tak, jakby jej suma była większa odn. Zacznij sumę od1, a wyszukiwanie od2. - Uznawanie
1za liczbę doskonałą. Gdy suma zaczyna się od1, dla wejściowej wartości1porównanie ma postać1 == 1. Suma jej właściwych dzielników wynosi0, więc obsłuż ten przypadek przed pętlą. - Dodawanie pierwiastka kwadratowego dwukrotnie. Dla
16właściwe dzielniki to1,2,4i8, a ich suma wynosi15. Dwukrotne dodanie4daje19. - Zatrzymywanie się przy
d * d < n. To pomija pierwiastek kwadratowy, więc4dla16nigdy nie zostaje uwzględnione. - Wyznaczanie granicy na podstawie pierwiastka kwadratowego w liczbie zmiennoprzecinkowej. W przypadku pojedynczej precyzji lub dla liczb większych niż
2^53w podwójnej precyzji pierwiastek z kwadratu doskonałego może być zaokrąglony w dół o jeden, przez co dzielnik zostanie pominięty. Testd * d ≤ noperuje na liczbach całkowitych i nigdy nie sprawia tego problemu.
Najczęstsze pytania4
C jaka jest złożoność czasowa sprawdzania, czy liczba jest doskonała?
Zbieranie par dzielników do √n zajmuje O(√n) czasu i O(1) pamięci. Dla n = 10^8 to około 10^4 kroków. Testowanie każdego kandydata do n / 2 ma złożoność O(n) i dla tych samych danych wejściowych wymaga około 5 × 10^7 kroków.
Ile liczb doskonałych jest mniejszych niż 10^8?
Pięć: 6, 28, 496, 8128 i 33550336. Szybko stają się coraz rzadsze. Kolejna, 8589869056, nie mieści się nawet w 32-bitowej liczbie całkowitej.
Czy istnieją nieparzyste liczby doskonałe?
Nikt nie wie. Każda dotychczas znaleziona liczba doskonała jest parzysta. Poszukiwania wykluczyły istnienie nieparzystych liczb doskonałych mniejszych niż 10^1500, ale nie ma dowodu, że nie mogą istnieć. Twoja funkcja musi działać zgodnie z definicją, a nie na podstawie przypuszczenia, że dane wejściowe są parzyste.
Jaka jest różnica między liczbami doskonałymi, obfitymi i niedoborowymi?
Porównaj sumę dzielników właściwych z daną liczbą. Równość oznacza liczbę doskonałą, taką jak 28. Większa suma oznacza liczbę obfitą, taką jak 12, której dzielniki sumują się do 16. Mniejsza suma oznacza liczbę niedomiarową, taką jak każda liczba pierwsza, której jedynym dzielnikiem właściwym jest 1.
Podobne zadania
Zadania oparte na tych samych pomysłach. Rozwiązanie dwóch lub trzech utrwala schemat.
Python
def isPerfect(n):
# Napisz kod tutajPrzypadek 1
Przypadek 2
Przypadek 3
Wejście
n = 28
Oczekiwane
true