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

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

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

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

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

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

Пример 1

Два игрока, Петя и Ваня, играют в игру. Перед ними лежит куча камней. Игроки ходят по очереди, первый ход делает Петя. За один ход можно добавить в кучу один камень, добавить четыре камня или увеличить количество камней в два раза. Игра завершается, когда в куче становится не менее 45 камней. Победителем считается игрок, сделавший последний ход. В начальный момент в куче S камней, 1 ≤ S ≤ 44. Найдите три значения S, при которых у Пети есть выигрышная стратегия, причём Петя не может выиграть первым ходом, но может выиграть своим вторым ходом независимо от того, как будет ходить Ваня. Найденные значения запишите в порядке возрастания.
Показать решение и ответ
1. Петя выигрывает вторым ходом, если может первым ходом получить кучу, из которой Ваня проигрывает при любом ходе. Из задания 19 такая куча одна — 22. 2. Ищем S < 22, из которых одним ходом получается 22: S + 1 = 22 → 21; S + 4 = 22 → 18; S · 2 = 22 → 11. 3. Проверяем, что ни из одного из них Петя не выигрывает первым ходом: максимум 21 · 2 = 42 < 45. 4. Ответ: 11, 18, 21. Проверка программой (функция 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([s for s in range(1, 45) if game(s) == 'W2'])   # Петя выигрывает ровно вторым ходом: [11, 18, 21]

Ответ: 11 18 21

Пример 2

Два игрока, Петя и Ваня, играют в игру. Перед ними лежит куча камней. Игроки ходят по очереди, первый ход делает Петя. За один ход можно добавить в кучу два камня или увеличить количество камней в три раза. Игра завершается, когда в куче становится не менее 70 камней. Победителем считается игрок, сделавший последний ход. В начальный момент в куче S камней, 1 ≤ S ≤ 69. Найдите два значения S, при которых у Пети есть выигрышная стратегия, причём Петя не может выиграть первым ходом, но может выиграть своим вторым ходом независимо от того, как будет ходить Ваня. Найденные значения запишите в порядке возрастания.
Показать решение и ответ
1. Позиции, где ходящий проигрывает (соперник выигрывает первым ходом при любом ходе): 22 и 23 — проверено в задании 19 этого варианта. 2. Петя выигрывает вторым ходом, если первым ходом может поставить Ваню в 22 или 23. 3. «+2»: S = 20 или 21. Утроением 22 и 23 не получить. 4. Из 20 и 21 Петя первым ходом не выигрывает: 21 · 3 = 63 < 70. 5. Ответ: 20 21. Проверка программой:
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([s for s in range(1, 70) if game(s) == 'W2'])   # [20, 21]

Ответ: 20 21

Пример 3

Два игрока, Петя и Ваня, играют в игру. Перед ними лежит куча камней. Игроки ходят по очереди, первый ход делает Петя. За один ход можно добавить в кучу один или два камня или увеличить количество камней в три раза. Игра завершается, когда в куче становится не менее 60 камней. Победителем считается игрок, сделавший последний ход. В начальный момент в куче S камней, 1 ≤ S ≤ 59. Найдите два значения S, при которых у Пети есть выигрышная стратегия, причём Петя не может выиграть первым ходом, но может выиграть своим вторым ходом независимо от того, как будет ходить Ваня. Найденные значения запишите в порядке возрастания.
Показать решение и ответ
1. Проигрышная позиция для ходящего (из задания 19 этого варианта) одна — 19. 2. Петя должен первым ходом получить 19: «+1» → S = 18, «+2» → S = 17, утроением 19 не получить. 3. Из 17 и 18 Петя сразу не выигрывает: 18 · 3 = 54 < 60. 4. Ответ: 17 18. Проверка программой:
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) == 'W2'])   # [17, 18]

Ответ: 17 18

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

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

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

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

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