Рекурсия в ЕГЭ по информатике: как вычислить функцию на Python и не упасть по глубине

· 3 мин чтения · Редакция Skill Unit

В задании на рекурсию дана функция, которая определяется через саму себя, и нужно найти её значение для какого-то n. Вручную такие задачи решают по таблице, но на экзамене надёжнее и быстрее написать короткую программу. Разберём, как перенести условие в код без ошибок и что делать, когда Python отказывается считать.

Шаг 1. Перепишите условие дословно

Условие обычно выглядит так: F(n) = n при n < 3; F(n) = F(n − 1) + 2·F(n − 2) при n ≥ 3. Найдите F(25). Главное правило: каждая строка условия становится строкой кода, порядок проверок тот же. Сначала базовый случай, потом общий.

Python
def F(n):
    if n < 3:
        return n
    return F(n - 1) + 2 * F(n - 2)

print(F(25))

Программа выведет 16777216. Для проверки посчитайте вручную пару первых значений: F(1) = 1, F(2) = 2, F(3) = 2 + 2 = 4, F(4) = 4 + 4 = 8. Видна закономерность: значения удваиваются, и F(25) = 2²⁴ = 16 777 216. Совпадение ручной проверки с программой — лучший признак, что условие перенесено верно.

Шаг 2. Если считает слишком долго — добавьте кэш

Функция выше вызывает себя дважды, и число вызовов растёт очень быстро: для n около 40 программа может считать минутами. Причина в том, что одни и те же значения пересчитываются много раз. Решение — запоминать уже найденные значения. В Python для этого есть декоратор lru_cache из модуля functools.

Python
from functools import lru_cache

@lru_cache(None)
def F(n):
    if n < 3:
        return n
    return F(n - 1) + 2 * F(n - 2)

print(F(100))

Теперь каждое значение считается один раз, и даже F(100) выводится мгновенно. Одна строка импорта и одна строка декоратора — запомните их как шаблон.

Шаг 3. Если ошибка RecursionError

Когда просят значение для n в несколько тысяч, Python может остановиться с ошибкой о превышении глубины рекурсии: по умолчанию он разрешает около тысячи вложенных вызовов. Есть два рабочих приёма.

  • Поднять предел: import sys и sys.setrecursionlimit(10000). Помогает, если нужная глубина не слишком велика.
  • Заполнить кэш снизу вверх: в цикле вызвать функцию для n = 1, 2, 3 и так далее до нужного. Каждый следующий вызов опирается на уже посчитанное значение, и глубина остаётся маленькой.

Пример: G(1) = 1, G(n) = G(n − 1) + n. Найдите G(3000) − G(2995).

Python
from functools import lru_cache

@lru_cache(None)
def G(n):
    if n == 1:
        return 1
    return G(n - 1) + n

for i in range(1, 3001):
    G(i)

print(G(3000) - G(2995))

Ответ 14990. Проверка в уме: разность равна 2996 + 2997 + 2998 + 2999 + 3000 = 14 990. Обратите внимание: в таких задачах часто просят именно разность или частное, потому что сами значения огромные. Python работает с большими целыми числами без потери точности, так что считать «в лоб» можно.

Типичные ошибки

  • Перепутан порядок проверок: общий случай стоит раньше базового, и функция уходит в бесконечные вызовы.
  • Строгое и нестрогое неравенство: «при n < 3» и «при n ≤ 3» дают разные ответы.
  • Деление: если в условии целочисленное деление, пишите //, а не /, иначе получите дробь.
  • Две функции, которые вызывают друг друга: обе нужно описать до первого вызова и обе закэшировать.
  • Ответ не проверен на маленьких n: две-три строки ручного счёта ловят большинство опечаток.

Как тренироваться

Возьмите десять условий с рекурсией из открытого банка ФИПИ и для каждого сделайте три вещи: ручной расчёт для n = 1…4, программу без кэша, программу с кэшем. Через неделю шаблон будет писаться за минуту, а время на экзамене уйдёт на задачи, где нужно думать.

Рекурсию, перебор, работу с файлами и все остальные типы заданий разбирают в курсе «ЕГЭ по информатике» — с задачами на Python и мгновенной проверкой ответов.

Хотите пройти путь на практике?

Курс «ЕГЭ по информатике»: короткие уроки, практические задания и проверка ответов. Первый урок бесплатно.

Смотреть курс