Задача к ЕГЭ по информатике на тему «Маски» №2

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

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

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

Например, маске 123*4?5 соответствуют числа 123405 и 12300405. Среди натуральных чисел, не превышающих  107  , найдите все числа, соответствующие маске 2*56??, делящиеся на 2048 без остатка, у которых более 5 делителей, соответствующих маске 1*4. В ответе запишите все найденные числа в порядке возрастания, и через пробел – соответствующие им результаты деления этих чисел на 2048.

Решение через fnmatch

from fnmatch import fnmatch
def divs(x):#функция поиска делителей для определенного числа
    d = set()
    for i in range(1,int(x**0.5)+1):
        if x % i == 0:
            d |= {i,x//i}
    return sorted(d)
# для оптимизации делаем цикл с шагом 2048, начиная с числа кратного 2048, для того чтобы проходиться по числам кратным 2048
for x in range(4096,10**7+1,2048):
    if fnmatch(str(x),’2*56??’):#если число удовлетворяет маске числа
        d = [i for i in divs(x) if fnmatch(str(i),’1*4’)]#делаем список,в котором будут делители,
        #удовлетворяющие маске делителей.
        if len(d) > 5:
            print(x,x//2048)

Решение через itertools

from itertools import product
def divs(x): #функция поиска делителей для определенного числа
    d = set()
    for i in range(1,int(x**0.5)+1):
        if x % i == 0:
            d |= {i,x//i}
    return sorted(d)
digits = ’0123456789’
res = []#список, в котором будут числа удовлетворяющие маске числа
need_div = []#список, в котором будут числа удовлетворяющие маске делителей
#формирование чисел по определенной маске чисел
for i in range(3):
    for digit_1 in product(digits,repeat = i): # cимулируем звёздочку
        for digit_2 in product(digits,repeat = 1): # симулируем вопрос
            for digit_3 in product(digits,repeat = 1): # симулируем вопрос
                res += [int(’2’ + ’’.join(digit_1) + ’56’ + ’’.join(digit_2) + ’’.join(digit_3))]
#формирование чисел по определенной маске делителей
for i in range(6):
    for digit_1 in product(digits,repeat = i): # симулируем звёздочку
        need_div += [int(’1’+’’.join(digit_1) + ’4’)]
for x in sorted(set(res)):#проход по всевозможным получившимся числам
    if x <= 10**7 and x % 2048 == 0:
        d = [i for i in divs(x) if i in need_div]#список, в котором будут делители числа,
        # удовлетворяющие маске делителей
        if len(d) > 5:#если таких делителей больше 5
            print(x,x//2048)

Решение через срезы

def divs(x): # функция, которая возвращает список делителей числа
    d = set()
    for i in range(1,int(x**0.5)+1):
        if x % i == 0:
            d.add(i)
            d.add(x//i)
    return sorted(d) # возвращаем отсортированный список делителей

# для оптимизации делаем цикл с шагом 2048, начиная с числа кратного 2048, для того чтобы проходиться по числам кратным 2048
for x in range(26624,10**7+1,2048):
    n = str(x)
    if n[0] == ’2’ and ’56’ in n[-4:-2]: # проверка, что число соответствует маске
        d = [i for i in divs(x) if str(i)[0] == ’1’ and str(i)[-1] == ’4’] # список делителей числа, которые удовлетворяют маске делителей
        if len(d) > 5: # если таких делителей больше 5
            print(x,x//2048)

Ответ: 2715648 1326
Оцените статью
Я решу все!