Задание №25 ЕГЭ по информатике: разбор, шаблоны кода Python и анти-примеры | СмартКИМ
СмартКИМ УДОБНАЯ ПОДГОТОВКА К ЕГЭ И ОГЭ
Задачи №25 Решать в тренажере Войти в СмартКИМ
ЕГЭ (1–27) ОГЭ (1–15) Python: шпаргалка
Быстрый переход по номерам и темам
Повышенный (1 балл) Время: 3-5 мин Python fnmatch Поиск делителей за O(sqrt(N)) Все задачи №{ topic_num } в каталоге

Задание №25. Обработка целочисленной информации (Маски и делители)

Тема: Функция fnmatch для масок (? и *), поиск делителей за O(sqrt(N)) и простые числа
Поиск чисел по маске (символы `?` — ровно один, `*` — любое количество) или чисел с особыми свойствами делителей.

1. Модуль fnmatch для проверки масок:

  • ? — ровно один любой символ.
  • * — любая (в том числе пустая) последовательность символов.
  • from fnmatch import fnmatch; if fnmatch(str(n), '12*34?5'): ...

2. Эффективный поиск делителей за $O(\sqrt{N})$:

def get_divisors(n):
    divs = set()
    for d in range(1, int(n**0.5) + 1):
        if n % d == 0:
            divs.add(d)
            divs.add(n // d)
    return sorted(divs)

Разновидности и прототипы задания на экзамене

Тип 1: Поиск чисел по маске, кратных K (fnmatch)
Перебор `range(0, 10**10, K)` с проверкой `fnmatch(str(n), mask)`.
Тип 2: Поиск делителей числа за O(sqrt(N))
Сбор пар `d` и `n // d` до `int(n**0.5)`.

Боевой шаблон решения на Python

Запустить код в онлайн-песочнице
# === Боевой шаблон Задания №25 на Python ===
from fnmatch import fnmatch

# Тип 1: Поиск чисел по маске '12?4*56', кратных 3123:
mask = "12?4*56"
divisor = 3123
max_limit = 10**9

# Шагаем строго с шагом divisor (в 3123 раза быстрее!):
for n in range(divisor, max_limit, divisor):
    if fnmatch(str(n), mask):
        print(n, n // divisor)

# Тип 2: Поиск чисел с ровно 5 нетривиальными делителями:
def count_divs(n):
    divs = []
    for d in range(2, int(n**0.5) + 1):
        if n % d == 0:
            divs.append(d)
            if d != n // d:
                divs.append(n // d)
    return sorted(divs)

Анти-примеры (Типичные ошибки vs Как делать правильно)

Как делать НЕ надо:
Ошибка: Перебирать ВСЕ числа с шагом 1: for n in range(10**9):
1 миллиард итераций будет выполняться 15 минут!
Как делать ПРАВИЛЬНО:
Правильно: Шагать сразу с шагом делителя: for n in range(div, 10**9, div):
ГРОБ

ГРОБ №25: Число делителей у чисел порядка 10^12

Числа слишком большие для наивного перебора.

Как обойти ловушку: Генерируйте числа напрямую по маске, перебирая цифры на месте `?` и `*`.

Лайфхаки и подводные камни на экзамене:

  • Всегда шагайте с шагом делителя `range(div, limit, div)` — код выполнится за 0.1 секунды!
Банк реальных задач №25 Открыть в тренажере СмартКИМ