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

Для игры, описанной в предыдущем задании, найдите два наибольших значения S, при которых у Пети есть выигрышная стратегия, причём одновременно выполняются два условия:

— Петя не может выиграть за один ход;

— Петя может выиграть своим вторым ходом независимо от того, как будет ходить Ваня.

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

Решение руками

Из предыдущего задания мы знаем, что в значениях (22,24,26,28,30,32,34,36,38,40,42,43)  Ваня побеждает своим первым ходом. Значение, из которого ХОТЯ БЫ ОДИН ход ведет в вышеуказанный список значений – это значение, в котором Петя выигрывает вторым ходом. Распишем два максимальных значения и стратегии, при которых Петя побеждает своим вторым ходом:

S = 39  . Петя может увеличить количество камней до 40  ходом + 1  или до 42  ходом + 3  .

S = 41  . Петя может увеличить количество камней до 42  ходом + 1  .

Ответ: 3941

Решение БУ

from functools import lru_cache
@lru_cache(None)
def game(first_heap): # функция игры
    if first_heap >= 88: # если камней в куче стало больше 87
        return 0 # прекращаем игру
    moves = [] # cписок всех возможных ходов в партии
    if first_heap % 2 == 0: # если количество камней в куче является чётным
        # то можем сделать только ход *2, так как чётное*чётное = чётное
        moves = [game(first_heap*2)]
    else: # если количество камней в куче является нечётным
        # то можем сделать только любой ход, так как нечётное*чётное = чётное и нечётное + нечётное = чётное
        moves = [game(first_heap * 2),game(first_heap+1),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,88):
    # если в данной позиции возможен выигрыш Пети вторым ходом
    if game(i) == 2:
        print(i)

Решение АР

from functools import lru_cache
def moves(h):
    a = [h * 2]
    if (h + 1) % 2 == 0:
        a += [h + 1]
        a += [h + 3]
    return a
@lru_cache(None)
def f(h):
    if h >= 88:
        return ’END’
    if any(f(x) == ’END’ for x in moves(h)):
        return ’P1’
    if all(f(x) == ’P1’ for x in moves(h)):
        return ’V1’
    if any(f(x) == ’V1’ for x in moves(h)):
        return ’P2’
ans = []
for s in reversed(range(1, 88)):
    if f(s) == ’P2’:
        ans += [str(s)]
        if len(ans) == 2:
            break
print(ans[-1] + ans[-2])

 

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