К содержанию

Подтема 3 из 6

Числа с нужными делителями

Ровно k делителей, наибольшее количество делителей, величина M и наименьший делитель с его парой.

Ровно k делителей

Как найти числа, у которых ровно два делителя, не считая единицы и самого числа?

Перебрать числа, у каждого найти делители, отобрать нужные и сравнить их количество с двумя. Функция get_divisors из подтемы 2 делает самую трудную часть, остаётся перевести условие. Возьмём отрезок [10; 30], чтобы ответ можно было проверить в уме:

for n in range(10, 31):    D = [d for d in get_divisors(n) if 1 < d < n]    if len(D) == 2:        print(n, D[0], D[1])
10 2 5 14 2 7 15 3 5 21 3 7 22 2 11 26 2 13 27 3 9

У 10 без крайних остаются 2 и 5 — подходит. У 12 остаются 2, 3, 4, 6 — четыре, не подходит. У 27 остаются 3 и 9: подходит, хотя 9 не простое. «Два делителя» и «два простых делителя» — разные условия.

Для «ровно четыре чётных делителя» меняются только условие отбора и число: d % 2 == 0 и len(D) == 4. Само число тогда считается, если оно чётное: условие его не исключало.

Больше всего делителей

На отрезке [10; 30] найди число с наибольшим количеством делителей. Если таких несколько — наименьшее. Что нужно помнить по дороге?

Лучшее количество и число, у которого оно получилось. Новое число занимает их место, только если у него делителей больше.

best_count = 0best_number = 0for n in range(10, 31):    count = count_divisors(n)    if count > best_count:        best_count = count        best_number = n print(best_number, best_count)
24 8

По восемь делителей у 24 и у 30. Перебор идёт по возрастанию, 24 встречается раньше, а строгое > не даёт 30 его заменить. Со знаком >= при равенстве побеждало бы более позднее число, и ответом стало бы 30. Знак выбирают по правилу «если таких несколько».

Величина M

В условии часто вводят букву: «M — сумма двух наибольших делителей числа, не считая единицы и самого числа; если таких делителей нет, M = 0». Как с ней работать?

M — просто величина, которую считают по списку делителей. Главное — прочитать определение дословно и не забыть случай, когда делителей не хватает.

n = 48D = [d for d in get_divisors(n) if 1 < d < n]if len(D) >= 2:    M = D[-1] + D[-2]else:    M = 0print(D, M)
[2, 3, 4, 6, 8, 12, 16, 24] 40

Два наибольших делителя 48 — 24 и 16, M = 40. Другие определения считаются по тому же списку D — выбери:

сумма всех
sum(D) → 75
наибольший − наименьший
D[-1] - D[0] → 22
произведение двух наименьших
D[0] * D[1] → 6
сумма трёх наибольших
sum(D[-3:]) → 52

Осторожнее с нулём. У простого числа делителей без 1 и n нет, M = 0, а 0 % 10 == 0 — истина. Если условие хочет M, оканчивающееся на 0, все простые числа пройдут проверку по ошибке. Поэтому пишут M > 0 and M % 10 == 0 — если, конечно, условие само не разрешает M = 0.

Наименьший и наибольший

M — сумма наименьшего и наибольшего делителей без единицы и самого числа. Нужен ли для неё весь список делителей?

Нет: наименьший делитель больше 1 и наибольший меньше n — это одна пара. Найди первый делитель, начиная с 2, — второй даст деление. На парах делителей 84 это видно сразу:

Пары делителей 84. Внешняя пара (1, 84) не учитывается — она пунктирная. Следующая, выделенная (2, 42) — самая широкая из оставшихся: слева наименьший делитель больше 1, справа наибольший меньше 84.

Дуги вложены друг в друга: чем левее начало, тем правее конец. Для 84 это 2 и 84 // 2 = 42, для 105 — 3 и 35.

def calc_m(n):    for d in range(2, isqrt(n) + 1):        if n % d == 0:            return d + n // d    return 0 print(calc_m(84), calc_m(105), calc_m(13))
44 38 0

Перебор начинается с 2 — единица исключена — и останавливается на первом делителе: return сразу выходит из функции. У простого 13 делителей нет, функция вернёт 0. У 49 единственный такой делитель — 7, он и наименьший, и наибольший: M = 7 + 7 = 14, если условие не требует двух разных делителей.

Обоснование · необязательноПочему так для любого составного n

Пусть a — наименьший делитель n больше 1. Любой делитель b < n стоит в паре с n / b > 1, а чем больше один множитель пары, тем меньше другой. Самому маленькому a соответствует самый большой делитель меньше n — это n / a.

Первые после границы

Найди пять первых чисел больше 100, у которых M — сумма наименьшего и наибольшего делителей без 1 и n — оканчивается на 0. Как собрать программу?

Цикл из подтемы 1 — while found < 5 — с проверкой через calc_m внутри. Задачи этой подтемы так и устроены: перебор чисел снаружи, работа с делителями внутри.

n = 101found = 0while found < 5:    M = calc_m(n)    if M > 0 and M % 10 == 0:        print(n, M)        found += 1    n += 1
111 40 116 60 125 30 136 70 141 50

111 = 3 · 37, M = 40. 125 = 5 · 25 — наибольший делитель 25 не простой, но условие о простоте ничего не говорит. Без M > 0 первым ответом стало бы простое 101.

На экзамене граница бывает и 700 000, и 5 000 000 — программа та же. calc_m обычно находит делитель за несколько шагов, до √n идёт только для простых чисел, поэтому перебор укладывается в секунды.

Итого

  • Ровно kотобрать D и проверить len(D) == k
  • Больше всегопомнить лучшее количество и число
  • При равенстве«>» — первое из равных, «>=» — последнее
  • Величина Mопределение дословно, M = 0 — проверить отдельно
  • Наименьший и наибольшийодна пара: d и n // d
  • Первые после Nwhile found < k из подтемы 1

Проверьте себя

Ответь сначала сам, потом открой ответ.

Вопрос 1
Подходят ли 27 и 16 под условие «ровно два делителя, не считая единицы и самого числа»?
ОтветСкрыть ответ
Ответ
27 подходит: 3 и 9. 16 не подходит: у него три таких делителя — 2, 4 и 8.
Вопрос 2
В программе поиска числа с наибольшим количеством делителей на [10; 30] заменили > на >=. Что она выведет?
ОтветСкрыть ответ
Ответ
30 8: у 24 и 30 по восемь делителей, и при равенстве теперь побеждает более позднее число.
Вопрос 3
M — сумма двух наибольших делителей без единицы и самого числа, а если их меньше двух, M = 0. Чему равно M для 49 и для 50?
ОтветСкрыть ответ
Ответ
Для 49 — 0: у него один такой делитель, 7. Для 50 — 35: делители 2, 5, 10, 25, два наибольших — 25 и 10.
Вопрос 4
Что вернёт calc_m(91)? Сколько кандидатов d она проверит?
ОтветСкрыть ответ
Ответ
20: 91 = 7 · 13. Она проверит d = 2, 3, 4, 5, 6, 7 — шесть кандидатов — и остановится на 7.
Вопрос 5
Почему в поиске «M оканчивается на 0» нужно M > 0 and M % 10 == 0, а не просто M % 10 == 0?
ОтветСкрыть ответ
Ответ
У простых чисел M = 0, а 0 % 10 == 0 — истина. Без M > 0 в ответ попадут все простые числа.

Практика

Для проверки ответов нужен JavaScript. Условия, подсказки и решения доступны ниже.

Найди числа с четырьмя делителями от 20 до 40

Найди числа от 20 до 40, имеющие ровно четыре различных делителя без единицы и самого числа.

Запишите все строки ответа подряд в одну строку через пробел: в каждой строке число и его четыре делителя по возрастанию.

Выпиши пары делителей на отрезке

Найди среди чисел отрезка [235 400; 235 420] числа, у которых ровно два различных натуральных делителя, не считая единицы и самого числа. Для каждого найденного числа выведи эти два делителя в порядке возрастания; строки — в порядке возрастания чисел.

Запишите все строки ответа подряд в одну строку через пробел: в каждой строке два делителя по возрастанию.

Найди число с наибольшим количеством делителей

Среди чисел отрезка [1000; 1100] найди число с наибольшим количеством натуральных делителей. Если таких несколько, возьми наименьшее. Выведи количество делителей и само число.

Введите количество делителей и само число через пробел.

Вычисли M для числа 48

Пусть M — сумма двух наибольших различных делителей числа 48 без единицы и самого числа. Найди M.

Введите значение M.

Вычисли R по делителям на 8

Пусть R — сумма всех делителей числа, оканчивающихся на 8, не считая самого числа; если таких делителей нет, R = 0. Найди все числа отрезка [221 000; 221 040], для которых R оканчивается на 6. Для каждого выведи число и R.

Запишите все строки ответа подряд в одну строку через пробел: в каждой строке число и R.

Вычисли calc_m для трёх чисел

Чему равно calc_m(91), calc_m(97) и calc_m(121)?

Введите три значения через пробел: calc_m(91), calc_m(97), calc_m(121).

Найди близкие делители у чисел с четырьмя делителями

Рассматриваются числа, большие 800 000, у которых ровно четыре натуральных делителя. Найди шесть первых таких чисел, у которых наименьший и наибольший делители, не считая единицы и самого числа, отличаются не более чем на 15. Для каждого выведи число и эту разность.

Запишите все строки ответа подряд в одну строку через пробел: в каждой строке число и разность делителей.

Найди пять чисел с M, оканчивающимся на 6

Пусть M — сумма наименьшего и наибольшего натуральных делителей числа, не считая единицы и самого числа. Если таких делителей нет, M = 0. Найди пять наименьших чисел, больших 600 000, для которых M больше нуля и оканчивается цифрой 6. Для каждого выведи число и M.

Запишите все строки ответа подряд в одну строку через пробел: в каждой строке число и M.

Найди пять чисел с M(N), кратным 101

Пусть M(N) — сумма двух наибольших различных натуральных делителей числа N, не считая единицы и самого N. Если таких делителей меньше двух, M(N) = 0. Найди пять наименьших чисел, больших 2 000 000, для которых M(N) больше нуля и делится на 101. Для каждого выведи N и M(N).

Запишите все строки ответа подряд в одну строку через пробел: в каждой строке N и M(N).

Найди делители, оканчивающиеся на 14

Найди пять наименьших чисел, больших 600 000, у которых есть натуральный делитель, оканчивающийся на 14 и не равный ни самому числу, ни числу 14. Для каждого выведи число и наименьший такой делитель.

Запишите все строки ответа подряд в одну строку через пробел: в каждой строке число и наименьший подходящий делитель.