№ 6210 (Уровень: Средний)
(Н. Сафронов) Назовём маской числа последовательность цифр, в которой также могут встречаться следующие символы:
— символ «?» означает ровно одну произвольную цифру;
— символ «» означает любую последовательность цифр произвольной длины; в том числе «» может задавать и пустую последовательность.
Например, маске 123*4?5 соответствуют числа 123405 и 12300425.
Найдите все натуральные числа, не превосходящие 10**7, для которых выполняются одновременно все условия:
В ответе запишите в первом столбце таблицы все найденные числа в порядке возрастания, а во втором столбце — сумму делителей.
Комментарии к коду решения:
from fnmatch import *
- Импортируем все функции из модуляfnmatch
для использования функцииfnmatch
.def divisors(num):
- Определяем функциюdivisors
с аргументомnum
для поиска делителей числа.div = []
- Инициализируем пустой списокdiv
для хранения делителей.for j in range(1, int(num**0.5)+1):
- Запускаем итерацию по значениям от 1 до квадратного корня числаnum
(такой подход помогает быстро найти все сомножители делителей).if num % j == 0:
- Проверяем является лиj
делителем числаnum
.div.append(j)
- После чего добавляемj
в список делителейdiv
.div.append(num // j)
- Так же добавляемnum // j
(сомножительj
) в список делителей.return sorted(set(div))
- Возвращаем отсортированное множество уникальных делителей (елси у числа есть целый квадратный корень, то могут появится копии делителя).for x in range(53, 10**7, 53):
- После определения функции нужно запустить итерацию по значениямx
от 53 до 10**7 с шагом 53, чтобы получить все числа делящиеся на 53.if fnmatch(str(x), '*2?2*'):
- Проверяем, соответствует ли строковое представление числаx
нашей маске*2?2*
.if str(x) == str(x)[::-1]:
- Так может выглядеть простая проверка на палиндромом.d = divisors(x)
- Вызываем нашу функциюdivisors
для определения делителей числаx
.if len(d) > 30:
- Проверяем кол-во делителей числаx
(по условию больше 30).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))