Разбор 25.PNG

№ 6210 (Уровень: Средний)

(Н. Сафронов) Назовём маской числа последовательность цифр, в которой также могут встречаться следующие символы:

— символ «?» означает ровно одну произвольную цифру;

— символ «» означает любую последовательность цифр произвольной длины; в том числе «» может задавать и пустую последовательность.

Например, маске 123*4?5 соответствуют числа 123405 и 12300425.

Найдите все натуральные числа, не превосходящие 10**7, для которых выполняются одновременно все условия:

В ответе запишите в первом столбце таблицы все найденные числа в порядке возрастания, а во втором столбце — сумму делителей.

Untitled

Комментарии к коду решения:

  1. from fnmatch import * - Импортируем все функции из модуля fnmatch для использования функции fnmatch.
  2. def divisors(num): - Определяем функцию divisors с аргументом numдля поиска делителей числа.
  3. div = [] - Инициализируем пустой список div для хранения делителей.
  4. for j in range(1, int(num**0.5)+1): - Запускаем итерацию по значениям от 1 до квадратного корня числа num (такой подход помогает быстро найти все сомножители делителей).
  5. if num % j == 0: - Проверяем является ли j делителем числа num.
  6. div.append(j) - После чего добавляем j в список делителей div.
  7. div.append(num // j) - Так же добавляем num // j (сомножитель j) в список делителей.
  8. return sorted(set(div)) - Возвращаем отсортированное множество уникальных делителей (елси у числа есть целый квадратный корень, то могут появится копии делителя).
  9. for x in range(53, 10**7, 53): - После определения функции нужно запустить итерацию по значениям x от 53 до 10**7 с шагом 53, чтобы получить все числа делящиеся на 53.
  10. if fnmatch(str(x), '*2?2*'): - Проверяем, соответствует ли строковое представление числа x нашей маске *2?2*.
  11. if str(x) == str(x)[::-1]: - Так может выглядеть простая проверка на палиндромом.
  12. d = divisors(x) - Вызываем нашу функцию divisors для определения делителей числа x.
  13. if len(d) > 30: - Проверяем кол-во делителей числа x (по условию больше 30).
  14. print(x, sum(d)) - Вывод все подходящие числа x и суммы его делителей.
from fnmatch import *

def divisors(num):
    div = []
    for j in range(1, int(num**0.5)+1):
        if num % j == 0:
            div.append(j)
            div.append(num // j)
    return sorted(set(div))

for x in range(53, 10**7, 53):  # • делятся на число 53 без остатка;
    if fnmatch(str(x), '*2?2*'):  # • соответствуют маске *2?2*;
        if str(x) == str(x)[::-1]:  # • являются палиндромами;
            d = divisors(x)
            if len(d) > 30:  # • количество делителей больше 30.
                print(x, sum(d))

Ответ: