BitNeBolt
@BitNeBolt

Как решить задачу?

Задача

Моё решение:
n = int(input())
 
elems = set()
 
for i in range(0, 22):
    for j in range(0, 22):
        for k in range(0, 22):
            elems.add(2 ** i * 3 ** j * 5 ** k)
 
elems = sorted(elems)        
print(elems[n-1])


Для первых тестов работает нормально, простых чисел и кратных им (кроме 2, 3 и 5) вроде не выдает (просматривал вручную некоторые).

Что не так? В чем суть задачи?
  • Вопрос задан
  • 154 просмотра
Решения вопроса 1
wataru
@wataru Куратор тега Алгоритмы
Разработчик на С++, экс-олимпиадник.
Вы правильно поняли, какого вида числа будут в последовательности (перемноженные степени 2, 3 и 5).

Проблема в том, что вы, например, пропустите число 2^23, которое входит в первые 10000.

Вам надо поднимать границы от 22, пока сгенерированная последовательность (первые 10000 чисел) не перестанет менятся. Вы сгенерируете первые 10000 чисел точно, и какие-то дальше в последовательности (возможно с пропусками) - всего будет сильно больше 10000 чисел.

Но скорее всего, придется поменять алгоритм. Поскольку ограничения маленькие, то тут можно делать что-то типа BFS. Вы вычисляйте числа в последовательности по порядку. И поддерживайте множество возможных следующих чисел. Каждый раз дописывайте минимальное число из кандидатов к последовательности и добавляйте к кандидатам это новое число, умноженное на 2, на 3 или на 5. Это будет квадратичный алгоритм. Можно использовать heap или какой-нибудь set, тогда будет за O(n log n).

Еще есть линейный алгоритм. Он получается из предыдущего так: все кандидаты разбейте на 3 множества - те, которые получены домножением на 2, на 3 и на 5. Каждое такое множество в итоге будет тупо сама же последовательность, домноженная на 2, 3 или 5. Поэтому единственное, что вам надо знать для полного описания кандидатов - это какое число из последовательности было домножено на 2,3 или 5. Это три индекса.

Т.е. решение будет поддерживать три индекса в уже сгенерированном массиве. Потом смотреть, какое число, домноженное на соответсвующий множитель минимально, это число дописывать в последовательность и этот индекс сдвигать на 1.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
BorLaze
@BorLaze
Java developer
Ты неправильно генеришь данные.

Смотри:
1 шаг: в массиве только [1] (число 1 является элементом последовательности)
2 шаг: берем 1, добавляем 2, 3, 5 (если a – элемент последовательности, то 2a, 3a, 5a тоже являются элементами последовательности) - а равно 1, в итоге получаем [1, 2, 3, 5]
3 шаг: берем 2, добавляем 2*2, 3*2, 5*2 (а теперь равно второму элементу, 2), сортируем: [1, 2, 3, 4, 5, 6, 10]
4 шаг: берем 3... ну, и так далее.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы