Задание 16 ЕГЭ по информатике на Python: рекурсивные функции

опубликовано
читать
≈ 3 мин
автор
среда и версия
Python 3.14.2 в браузере (Pyodide 314.0.3) — там же, где запускаются примеры на странице; вывод совпал с CPython 3.14.7
содержание решать задачи Python для начинающих

В задании 16 ЕГЭ по информатике функция задана через саму себя: F(n) выражается через F(n + 2) или F(n − 1), а для крайних n дано готовое значение. Спрашивают значение выражения с этой функцией. На Python условие переписывается почти дословно — функцией с def. Подвох в глубине: цепочка вызовов бывает длиннее 1000, и тогда Python останавливает программу. Примеры ниже запускаются прямо на странице и составлены для этой статьи: на экзамене функции и числа будут другими, а приёмы — те же.

ЕГЭ / 01

F(14) ждёт F(16), та — F(18), и так до F(3000)

F(14) ждёт F(16), та — F(18), и так до F(3000)F(14) = 16 + F(16), F(16) = 18 + F(18), F(18) = 20 + F(20) и так далее до F(3000) = 3000, где рекурсия кончается. От F(14) до F(3000) — 1 494 вызова один в другом, это больше предела 1000, поэтому без sys.setrecursionlimit Python остановит программу. Разность F(14) − F(18) сокращается: 16 + 18 = 34.1 · каждый вызов ждёт следующегоF(14)F(16)F(18)…F(3000) = 300016 + F(16)18 + F(18)20 + F(20)n ≥ 3000 — без рекурсии2 · глубина и ответот F(14) до F(3000) — 1 494 вызова один в другом, больше предела 1000F(14) − F(18) = 16 + 18 = 34
Глубина рекурсии — длина такой цепочки. Python по умолчанию разрешает 1000 вызовов, поэтому для F(14) предел поднимают. А ответ проверяют сокращением: F(18) в разности исчезает.

Пример задачи

Функция F(n) задана так:

  • F(n) = n при n ≥ 3000;
  • F(n) = n + 2 + F(n + 2) при n < 3000.

Чему равно значение выражения F(14) − F(18)?

Решение

import sys
sys.setrecursionlimit(10000)

def F(n):
    if n >= 3000:
        return n
    return n + 2 + F(n + 2)

print(F(14) - F(18))
34
  • Функция повторяет условие: сначала случай без рекурсии (n ≥ 3000), потом — через F(n + 2).
  • F(14) вызывает F(16), та — F(18), и так до F(3000): 1 494 вызова один в другом. По умолчанию Python разрешает глубину 1000, поэтому sys.setrecursionlimit(10000) поднимает предел с запасом.

Ответ: 34.

Проверка сокращением. F(14) = 14 + 2 + F(16) = 16 + F(16), а F(16) = 18 + F(18). Значит, F(14) − F(18) = 16 + 18 = 34, и до 3000 доходить не нужно.

Что будет без setrecursionlimit

def F(n):
    if n >= 3000:
        return n
    return n + 2 + F(n + 2)

print(F(14) - F(18))

Python остановит программу с ошибкой RecursionError: maximum recursion depth exceeded: цепочка из 1 494 вызовов длиннее разрешённой. Предел ставят с запасом над глубиной цепочки — здесь 10 000 хватает.

Большие числа

Другой вид: F(n) = 1 при n = 1 и F(n) = n · F(n − 1) при n > 1. Чему равно значение выражения (F(2024) + 2 · F(2023)) / F(2022)?

import sys
sys.setrecursionlimit(10000)

def F(n):
    if n == 1:
        return 1
    return n * F(n - 1)

print((F(2024) + 2 * F(2023)) // F(2022))
4098598

F(n) здесь — факториал n!, и в F(2024) 5 815 цифр. Python хранит целые числа любой длины и делит их точно, поэтому // даёт ответ без потерь.

Проверка сокращением. F(2024) = 2024 · 2023 · F(2022), а F(2023) = 2023 · F(2022). После деления на F(2022) остаётся 2024 · 2023 + 2 · 2023 = 2023 · 2026 = 4 098 598.

Частые ошибки

Нет setrecursionlimit. Цепочка длиннее 1000 вызовов останавливается с RecursionError, как в примере выше.

Печать огромного числа. print(F(2024)) останавливается с ошибкой ValueError: Exceeds the limit (4300 digits) for integer string conversion: Python не переводит в строку целые числа длиннее 4300 цифр. Печатать такое число и не нужно — после сокращения ответ небольшой. Если всё же нужно, предел снимает sys.set_int_max_str_digits(0).

/ вместо //. Обычное деление даст 4098598.0 — дробное число, а ответ в задании целый.

Две ветки рекурсии без кэша. Если F(n) выражается через F(n − 1) и F(n − 2), одни и те же значения считаются заново, и программа не закончится. Нужен lru_cache — пример в статье «Python для ЕГЭ по информатике».

Теория игр из заданий 19–21 решается такой же рекурсией — в статье «Задания 19–21 ЕГЭ на Python». Свой вариант удобно проверять в песочнице Python: пошаговое выполнение покажет, как вызовы уходят вглубь и возвращаются.

Источники