Вспоминай формулы по каждой теме
Решай новые задачи каждый день
Вдумчиво разбирай решения
ШКОЛКОВО.
Готовиться с нами - ЛЕГКО!
Подтемы раздела теория игр
Решаем задачу:

Ошибка.
Попробуйте повторить позже

Задача 1#26071

Два игрока, Петя и Ваня, играют в следующую игру. Перед игроками лежит куча камней. Игроки ходят по очереди, первый ход делает Петя. За один ход игрок может добавить в кучу один камень, увеличить количество камней в куче в два раза, увеличить количество камней в куче в три раза. Игра завершается в тот момент, когда количество камней в куче становится не менее 43  . Если при этом в куче оказалось не более 72  камней, то победителем считается игрок, сделавший последний ход. В противном случае победителем становится его противник. В начальный момент в куче было S  камней, 1 ≤ S ≤ 42  .

Найдите минимальное значение 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) == -1:  # Если в данной позиции Ваня гарантированно выигрывает своим первым ходом
        print(i)
        break  # Первое выведенное значение будет минимальным

Решение АР

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’

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

Ответ: 14

Специальные программы

Все специальные программы

Программа
лояльности v2.0

Приглашай друзей в Школково и получай вознаграждение до 10%!

Крути рулетку
и выигрывай призы!

Крути рулетку и покупай курсы со скидкой, которая привязывается к вашему аккаунту.

Бесплатное онлайн-обучение

Для школьников из приграничных территорий России, проживающих в ДНР, ЛНР, Херсонской, Запорожской, Белгородской, Курской, Брянской областях и Крыму.

Налоговые вычеты

Узнай, как получить налоговый вычет при оплате обучения в «Школково».

Специальное предложение
для учителей

Бесплатный доступ к любому курсу подготовки к ЕГЭ, ОГЭ и олимпиадам от «Школково». Мы с вами делаем общее и важное дело, а потому для нас очень значимо быть чем-то полезными для учителей по всей России!

Вернём деньги за курс
за твою сотку на ЕГЭ

Сдать экзамен на сотку и получить обратно деньги за подготовку теперь вполне реально!

cyberpunkMouse
cyberpunkMouse
Рулетка
Вы можете получить скидку в рулетке!