Oto szybkie, idiomatyczne rozwiązanie (szybsze od pozostałych oraz bardziej Pythonowe):
Kopiuj
import itertools
def najwpodzielne(limit, p, q, count):
return list(itertools.islice(filter(lambda x: x%p == 0 or x%q == 0, range(limit, 0, -1)), 0, count))
W szczególności, nawet jeśli limit = 10**8888, rozwiązanie to wciąż działa błyskawicznie, w przeciwieństwie do dwóch pozostałych.
Poza tym, podejście Guaza ( @Guaz ) jest na tyle zbyteczne, że operuje na tak wielkich zbiorach (rzędu limit/p), podczas gdy tak naprawdę użycie zbiorów w tym zadaniu jest całkowicie niepotrzebne - w każdych kolejnych pq liczbach całkowitych (p i q są względnie pierwsze), dokładnie p+q-1 dzięki się przez jedno z nich. Wobec tego, poprawnym rozwiązaniem jest rozważyć jedynie zbiór {0, 1, ..., pq}, wyznaczyć w nim wielokrotności p lub q (np metodą [0] + sorted(list(range(p, p*q, p))+list(range(q,p*q,q))), następnie wybierać z tej kolekcji pierwsze count liczb, poczynając od limit (mod p*q), idąc w dół, pamiętając o cyklicznej strukturze tej listy. Nie da się osiągnąć lepszej złożoności, gdyż liczba operacji jest proporcjonalna do rozmiaru listy, którą należy utworzyć. (pomijam preprocessing), ale też można założyć że (p+q)*log(p+q), czyli czas sortowania jest sporo mniejszy niżcount).