Задача к ЕГЭ по информатике на тему «Теория игр» №1

Для игры, описанной в задании #26071, найдите все значения S  , при которых одновременно выполняются два условия:

– у Вани есть выигрышная стратегия, позволяющая ему выиграть первым или вторым ходом при любой игре Пети;

– у Вани нет стратегии, которая позволит ему гарантированно выиграть первым ходом.

Найденные значения запишите в ответе в порядке возрастания без разделителей.

Решение БУ

from functools import lru_cache


@lru_cache(None)
def game(first_heap):  # Функция игры
    if first_heap > 72:  # Если камней в куче стало более 72
        return 1  # Возвращаем 1, означающую победу Вани "первым ходом" из-за плохого хода Пети
    if first_heap >= 43:  # Если камней в куче стало не менее 43
        return 0  # Прекращаем игру
    moves = [game(first_heap + 1), game(first_heap * 2), game(first_heap * 3)]  # Прописываем ходы возможные в партии
    petya_win = [i for i in moves if i <= 0]
    if petya_win:  # Проверяем есть ли выигрыш Пети в данной позиции
        return -max(petya_win) + 1
    else:  # Если в данной позиции выигрыш Вани
        return -max(moves)


for i in range(1, 42 + 1):
    if game(i) == -2:  # Если в данной позиции Ваня гарантированно выигрывает своим вторым ходом
        print(i)

Решение АР

from functools import lru_cache

def moves(h):
    return h + 1, h * 2, h * 3

@lru_cache(None)
def f(h):
    if h >= 43 and h <= 72:
        return ’END’
    if h > 72:
        return ’BAD’
    if any(f(x) == ’END’ for x in moves(h)):
        return ’WIN1’
    if all(f(x) == ’WIN1’ for x in moves(h)):
        return ’LOSE1’
    if all(f(x) == ’WIN1’ or f(x) == ’BAD’ for x in moves(h)):
        return ’LOSE1 or BAD’
    if any(f(x) == ’LOSE1’ for x in moves(h)):
        return ’WIN2’
    if any(f(x) == ’LOSE1 or BAD’ for x in moves(h)):
        return ’WIN2 or WIN(BAD for opponent)’
    if all(f(x) == ’WIN2’ or f(x) == ’WIN1’ for x in moves(h)):
        return ’LOSE2’
    if all(f(x) == ’WIN2’ or f(x) == ’WIN1’ or f(x)==’BAD’ or f(x)==’WIN2 or WIN(BAD for opponent)’
       for x in moves(h)):
        return ’LOSE2 or BAD’

for i in range(1, 43):
    if f(i) == ’LOSE2’ or f(i) == ’LOSE2 or BAD’:
        print(i)

Ответ: 1239
Оцените статью
Я решу все!