Вход


Главная страница >> Учебный процесс >> Задачник >> Олимпиадные задачи (с решениями) >> Разное >> Номер 4

[Назад]    [Содержание ]    [Вперед]

  


Номер 4


  Условие: Номер 4


Задача 4.1. Есть две обезьяны и куча из L бананов. Обезьяны по очереди, начиная с первой, берут из кучи бананы, причем 1-ая обезьяна может при каждом очередном ходе взять из кучи либо a1, либо a2, либо ... aS бананов (а1 <a2 <...<aS), а 2-ая при каждом очередном ходе --либо b1, либо b2, либо ... bK бананов (b1 <b2 <...<bK ). Нумерация индексов при a и b не имеет никакого отношения к номерам ходов обезьян Выигрывает та обезьяна, которая на своем ходе не может взять банан(ы) (либо потому, что их не осталось, либо потому что бананов осталось меньше чем a1 (при ходе первой обезьяны) либо b1 (при ходе второй обезьяны)). Определить может ли выиграть первая обезьяна при наилучших ходах соперницы, которая также стремится выиграть. Все входные данные - натуральные числа.

  Решение задачи: Номер 4


Решение задачи 4.1. Будем обозначать текущую ситуацию в игре парой (S,i), где S количество бананов, оставшихся в куче, перед текущим ходом i-ой обезьяны (i равно 1 или 2). Для того, чтобы (S,1) была выигрышной для игрока 1, среди возможных ситуаций после его хода (S-a1,2), ... ,(S-ak,2) должна быть хоть одна проигрышная для игрока 2 (в эту то ситуацию и надо будет перевести игру); если все ситуации выигрышные для игрока 2, то (S,1) - проигрышная для игрока 1 (как бы он не поступал, он все равно проиграет). Пусть ситуация после хода игрока 1 стала (S',2). Опять же делаем все допустимые ходы из этой позиции и смотрим является ли получившаяся ситуация (S",1) выигрышной, проигрышной или такой, которую мы еще не можем оценить. Если выполняется последняя альтернатива, то из (S",1) мы опять делаем все возможные ходы, анализируем, и т.д. Если мы в конце концов определили, для кого является выигрышной текущая позиция, то возвращаемся к предыдущему ходу и пытаемся определить, какая позиция для делающего ход и т. д., пока не вернемся к ситуации (L,1). const l1=200; s=10; var a: array [0..l1,1..2] of byte; {в ячейке a[L,i] хранится информация, кто выигрывает в ситуации (L,i)} b: array [1..2,0..s] of byte; {массив возможных ходов первого и второго игроков в b[i,0] хранится число возможных ходов игрока i} l,i,j:integer; Function f(ba:Integer;No: Byte): Byte; Var i,p,r: Byte; {рекурсивная функция вычисления (L,i)} Begin {f=i, если в (ba,i) выигрывает i} if Ba<0 {после хода монет <0?} Then f:= 3-No {выигрыш игрока с номером 3-Nо} else if ba=0 {монет = 0?} then begin {выигрыш No} f:=No; a[ba,no]:=no; end Else if a[ba,no]<>0 {в этой ситуации мы уже были} Then F := a[ba,no] {в ней выигрывает a[ba,no]} Else Begin {эту ситуацию мы еще не рассматривали} r := 0; {мы будем делать все возможные ходы} For i := 1 to b[No,0] do if ba-b[no,i]>=0 {если ход возможен, то делаем его} then r := r or F(Ba-B[No,i],3-No); if r=0 then r:=no; If (No and R)<>0 {есть выигрышный ход?} Then p := No {да, (ba,i)=No} Else p := 3-No; {нет, (ba,i)=3-No} A[Ba,No]:=p; {запоминаем эту информацию} f:=p; End; end; begin for i:=0 to l1 do for j:=1 to 2 do A[i,j] := 0; write('s='); readln(b[1,0]); {b[1,0] = количество ходов первого игрока} for i:=1 to b[1,0] do begin write('a',i,'='); {сами ходы} Readln(b[1,i]); end; write('k='); Readln(b[2,0]); {b[2,0] = количество ходов второго игрока} For j := 1 to b[2,0] do begin write('b',j,'='); Readln(b[2,j]); {ввод ходов} end; repeat {для данных ходов вводятся значения L} write('L='); {число бананов} readln(l); if f(l,1)=1 {вызов рекурсивной функции-проверки} then writeln('1-я выиграла') else writeln('1-я проиграла'); for i:=1 to b[1,0] do {распечатка результатов возможных ходов} if (l-b[1,i])>=0 {из начальной позиции L} then writeln('b=',b[1,i],' winner=',a[l-b[1,i],2]); writeln; until false; end.

Назад



[Назад]    [Содержание ]    [Вперед]

  


  
За содержание страницы отвечает Гончарова М.Н.
©
Кафедра СПиКБ, 2002-2017