Пробный урок
📘 ЕГЭ по информатике 2027 · задание 21 из 27

Задание 21 ЕГЭ по информатике: Построение дерева игры и выигрышной стратегии

Что проверяет задание 21, сколько баллов оно приносит и сколько времени на него закладывать — и 3 примера в формате ФИПИ с подробным решением и ответом.

Уровень
высокий
Максимум
1 балл
Время
~10 минут
Компьютер
не нужен

Примеры задания 21 с решениями

Сначала попробуйте решить сами, затем откройте решение и сверьте ответ

Пример 1

Два игрока, Петя и Ваня, играют в игру. Перед ними лежит куча камней. Игроки ходят по очереди, первый ход делает Петя. За один ход можно добавить в кучу один камень, добавить четыре камня или увеличить количество камней в два раза. Игра завершается, когда в куче становится не менее 45 камней. Победителем считается игрок, сделавший последний ход. В начальный момент в куче S камней, 1 ≤ S ≤ 44. Найдите минимальное значение S, при котором у Вани есть выигрышная стратегия, позволяющая ему выиграть первым или вторым ходом при любой игре Пети, но нет стратегии, которая гарантированно позволит выиграть первым ходом.
Показать решение и ответ
1. Нужно S, при котором любой ход Пети ведёт в позицию, выигрышную для Вани за 1 или 2 хода, и хотя бы один ход — в позицию, где Ваня выигрывает только вторым ходом. 2. Позиции, где ходящий выигрывает первым ходом: 23–44. Вторым ходом (из задания 20): 11, 18, 21. 3. Перебираем S по возрастанию. S = 17: ходы 18, 21, 34. 18 и 21 — Ваня выигрывает вторым ходом, 34 — первым. Подходит. 4. Меньшие S не подходят. При S < 17 ход «+1» даёт кучу не больше 17, и среди таких куч выигрышная для Вани только 11 (это S = 10). Но из 10 ход «+4» даёт 14 — оттуда Ваня за два хода не выигрывает. 5. Ответ: 17. Проверка программой (функция game из задания 19):
from functools import lru_cache          # запоминаем уже посчитанные позиции, иначе перебор очень долгий

def moves(s):                            # все ходы из позиции s
    return [s + 1, s + 4, s * 2]         # +1 камень, +4 камня, удвоение

@lru_cache(None)                         # кэш результатов для каждой позиции
def game(s):                             # итог позиции для того, кто сейчас ходит
    if s >= 45:                          # игра уже окончена — ходящий проиграл
        return 'L0'                      # L0: проигрыш «за 0 ходов соперника»
    res = [game(t) for t in moves(s)]    # итоги позиций после каждого нашего хода (для соперника)
    lose = [r for r in res if r[0] == 'L']   # ходы, после которых соперник проигрывает
    if lose:                             # такой ход есть — мы выигрываем
        return 'W' + str(min(int(r[1:]) for r in lose) + 1)   # побеждаем как можно быстрее
    return 'L' + str(max(int(r[1:]) for r in res))           # все ходы плохие — проигрываем как можно позже
Обозначения: W1 — ходящий выигрывает первым ходом, W2 — вторым; L1 — соперник выигрывает своим первым ходом при любом ходе ходящего, L2 — первым или вторым.
print(min(s for s in range(1, 45) if game(s) == 'L2'))   # Ваня выигрывает первым или вторым ходом, но не гарантированно первым: 17

Ответ: 17

Пример 2

Два игрока, Петя и Ваня, играют в игру. Перед ними лежит куча камней. Игроки ходят по очереди, первый ход делает Петя. За один ход можно добавить в кучу два камня или увеличить количество камней в три раза. Игра завершается, когда в куче становится не менее 70 камней. Победителем считается игрок, сделавший последний ход. В начальный момент в куче S камней, 1 ≤ S ≤ 69. Найдите минимальное значение S, при котором у Вани есть выигрышная стратегия, позволяющая ему выиграть первым или вторым ходом при любой игре Пети, но нет стратегии, которая гарантированно позволит выиграть первым ходом.
Показать решение и ответ
1. Позиции, где ходящий выигрывает первым ходом: 24–69; вторым ходом: 20 и 21 (задание 20). 2. Нужно S, при котором оба хода Пети ведут в такие позиции, и хотя бы один — в 20 или 21. 3. S = 18: ходы 20 (W2) и 54 (W1) — подходит. Меньшие S: ход «+2» даёт кучу ≤ 19, а из 19 и меньше быстрого выигрыша нет. 4. Ответ: 18. Проверка программой:
from functools import lru_cache          # запоминаем уже посчитанные позиции

def moves(s):                            # все ходы из позиции s
    return [s + 2, s * 3]                # +2 камня или утроение

@lru_cache(None)                         # кэш результатов для каждой позиции
def game(s):                             # итог позиции для того, кто сейчас ходит
    if s >= 70:                          # игра уже окончена — ходящий проиграл
        return 'L0'                      # L0: проигрыш «за 0 ходов соперника»
    res = [game(t) for t in moves(s)]    # итоги позиций после каждого нашего хода (для соперника)
    lose = [r for r in res if r[0] == 'L']   # ходы, после которых соперник проигрывает
    if lose:                             # такой ход есть — мы выигрываем
        return 'W' + str(min(int(r[1:]) for r in lose) + 1)   # побеждаем как можно быстрее
    return 'L' + str(max(int(r[1:]) for r in res))           # все ходы плохие — проигрываем как можно позже
Обозначения: W1 — ходящий выигрывает первым ходом, W2 — вторым; L1 — соперник выигрывает своим первым ходом при любом ходе ходящего, L2 — первым или вторым.
print(min(s for s in range(1, 70) if game(s) == 'L2'))   # 18

Ответ: 18

Пример 3

Два игрока, Петя и Ваня, играют в игру. Перед ними лежит куча камней. Игроки ходят по очереди, первый ход делает Петя. За один ход можно добавить в кучу один или два камня или увеличить количество камней в три раза. Игра завершается, когда в куче становится не менее 60 камней. Победителем считается игрок, сделавший последний ход. В начальный момент в куче S камней, 1 ≤ S ≤ 59. Найдите значение S, при котором у Вани есть выигрышная стратегия, позволяющая ему выиграть первым или вторым ходом при любой игре Пети, но нет стратегии, которая гарантированно позволит выиграть первым ходом.
Показать решение и ответ
1. Выигрыш первым ходом — из 20–59, вторым — из 17 и 18 (задание 20 этого варианта). 2. S = 16: ходы 17 (W2), 18 (W2), 48 (W1) — все выигрышны для Вани, но не все за один ход. Подходит. 3. S = 15: ход 16 — из него Ваня быстро не выигрывает. Другие S < 16 тоже не подходят. При S = 17 и 18 выигрывает Петя, а при S = 19 Ваня выигрывает уже первым ходом. 4. Ответ: 16. Проверка программой:
from functools import lru_cache          # запоминаем уже посчитанные позиции

def moves(s):                            # все ходы из позиции s
    return [s + 1, s + 2, s * 3]         # +1, +2 или утроение

@lru_cache(None)                         # кэш результатов для каждой позиции
def game(s):                             # итог позиции для того, кто сейчас ходит
    if s >= 60:                          # игра уже окончена — ходящий проиграл
        return 'L0'                      # L0: проигрыш «за 0 ходов соперника»
    res = [game(t) for t in moves(s)]    # итоги позиций после каждого нашего хода (для соперника)
    lose = [r for r in res if r[0] == 'L']   # ходы, после которых соперник проигрывает
    if lose:                             # такой ход есть — мы выигрываем
        return 'W' + str(min(int(r[1:]) for r in lose) + 1)   # побеждаем как можно быстрее
    return 'L' + str(max(int(r[1:]) for r in res))           # все ходы плохие — проигрываем как можно позже
Обозначения: W1 — ходящий выигрывает первым ходом, W2 — вторым; L1 — соперник выигрывает своим первым ходом при любом ходе ходящего, L2 — первым или вторым.
print([s for s in range(1, 60) if game(s) == 'L2'])   # [16]

Ответ: 16

Не получается задание 21? Разберём на пробном уроке

Бесплатно покажем, как решать задание 21 и похожие, определим пробелы и составим план подготовки к ЕГЭ.

Записаться бесплатно

Все задания ЕГЭ по информатике

Структура экзамена, баллы и темы — на странице программы ЕГЭ по информатике