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

Задание 19 ЕГЭ по информатике: Анализ алгоритма логической игры

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

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

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

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

Пример 1

Два игрока, Петя и Ваня, играют в игру. Перед ними лежит куча камней. Игроки ходят по очереди, первый ход делает Петя. За один ход можно добавить в кучу один камень, добавить четыре камня или увеличить количество камней в два раза. Игра завершается, когда в куче становится не менее 45 камней. Победителем считается игрок, сделавший последний ход. В начальный момент в куче S камней, 1 ≤ S ≤ 44. Укажите минимальное значение S, при котором Ваня выигрывает своим первым ходом при любом ходе Пети.
Показать решение и ответ
1. Ваня выигрывает первым ходом, если любой ход Пети оставляет кучу, из которой можно сразу получить 45 или больше. 2. Сразу выиграть можно из кучи 23 и больше: 23 · 2 = 46. Из 22 — нельзя: 22 · 2 = 44, 22 + 4 = 26. 3. Значит, при S < 23 Петя не выигрывает первым ходом, а нам нужно, чтобы все его ходы вели в кучу ≥ 23. 4. Ход «+1» даёт S + 1 ≥ 23 → S ≥ 22. При S = 22: 23, 26 и 44 — из каждой Ваня выигрывает удвоением или «+1». 5. Минимальное S = 22. Проверка программой — общей для заданий 19–21:
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) == 'L1'))   # минимальное S, где Ваня выигрывает первым ходом: 22

Ответ: 22

Пример 2

Два игрока, Петя и Ваня, играют в игру. Перед ними лежит куча камней. Игроки ходят по очереди, первый ход делает Петя. За один ход можно добавить в кучу два камня или увеличить количество камней в три раза. Игра завершается, когда в куче становится не менее 70 камней. Победителем считается игрок, сделавший последний ход. В начальный момент в куче S камней, 1 ≤ S ≤ 69. Укажите минимальное значение S, при котором Ваня выигрывает своим первым ходом при любом ходе Пети.
Показать решение и ответ
1. Сразу выиграть можно из кучи 24 и больше: 24 · 3 = 72 ≥ 70. Из 23 — нельзя: 23 · 3 = 69. 2. Ваня выигрывает первым ходом, если любой ход Пети ведёт в кучу ≥ 24, а сам Петя сразу не выигрывает (S < 24). 3. Ход «+2» должен давать ≥ 24 → S ≥ 22. При S = 22: ходы 24 и 66 — из обеих Ваня выигрывает утроением. 4. Ответ: 22. Проверка программой (общая для заданий 19–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(min(s for s in range(1, 70) if game(s) == 'L1'))   # 22

Ответ: 22

Пример 3

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

Ответ: 19

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

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

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

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

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