Предсказать победу или поражение игрока, вопрос теории игр

Я пытаюсь решить этот вопрос.

Описание задачи: Дана сетка n*m, каждая ячейка либо пуста (обозначается .), либо имеет камень (обозначается *). Два игрока ходят по очереди, и каждый ход может:

1. переместить камень в соседнюю правую клетку, если эта ячейка пуста

2. Полностью удалить камень из сетки.

Мы должны найти, кто из игроков победит.

По сути, мой подход заключается в том, что всякий раз, когда количество камней и возможные ходы вправо четные/нечетные или наоборот, первый игрок всегда может выиграть, поскольку мы всегда можем уменьшить его до четного-четного, что, по моему мнению, является проигрышным состоянием.

Но я получаю неправильный ответ. Я не могу найти, где я ошибаюсь.

int main()
{
  int i,j,n,m,cnt,pos;
  char ch;
  while(true)
  {
      cin>>n>>m;
      if(n==0 && m==0)break;
      cnt=pos=0; //cnt store count of stones
      for(i=0;i<n;i++)
      {
            for(j=0;j<m;j++)
            {
                cin>>ch;
                if(ch=='*')
                {
                    cnt++;
                    pos+=(m-j-1); // this stone can be moved to m-j-1 places to right
                }
            }
      }
      if(cnt==1 || ((cnt&1)!=(pos&1)))cout<<"Player with first turn Wins"<<"\n";
      else cout<<"Player with second turn Wins"<<"\n";
    }
  return 0;
}

person Rajat Aggarwal    schedule 24.06.2020    source источник
comment
Пожалуйста, предоставьте описание проблемы в вопросе в виде текста. Пожалуйста, используйте осмысленные имена переменных.   -  person JohnFilleau    schedule 24.06.2020
comment
Не похоже, что вы обрабатываете условие завершения, где n и m равны нулю. Также стоит обратить внимание на то, как описан ввод. Если в вопросе в стиле конкурса говорится, сколько строк и даже какой символ находится в какой позиции в строке, то, если ваш код не обработка строкового ввода вообще должна быть гарантированной ошибкой для любого ввода, предназначенного для проверки этого ... Ну, вот как работают настоящие конкурсные вопросы. Возможно, SPO не проверяет способность следовать спецификации.   -  person paddy    schedule 24.06.2020
comment
@JohnFilleau Я обновил описание и переменные.   -  person Rajat Aggarwal    schedule 24.06.2020
comment
Вы даже не проверяете, содержит ли сетка камень, поэтому у вас нет основы, чтобы узнать, на сколько мест камень может быть сдвинут в любом направлении.   -  person paddy    schedule 24.06.2020
comment
@paddy Условие if(ch=='*) обрабатывает это.   -  person Rajat Aggarwal    schedule 24.06.2020
comment
Нет. В типичном стиле конкурса вопрос содержит простые примеры входных данных, предназначенные для того, чтобы обмануть поверхностных мыслителей и заставить их изобретать нестандартные решения. Что делать, если у вас есть большая доска с большим количеством камней? Как вы думаете, ваш pos += j трюк еще актуален?   -  person paddy    schedule 24.06.2020
comment
@paddy я обновил свой код. Кроме того, если в сетке нет камня, тогда «Игрок со вторым ходом побеждает», поскольку и pos, и cnt будут равны 0.   -  person Rajat Aggarwal    schedule 24.06.2020
comment
Не уверен, правильно ли код считает ходы. **. похоже на 2 хода и 2 камня, но я думаю, что код будет считать 3 хода и 2 камня.   -  person user3386109    schedule 24.06.2020
comment
@user3386109 user3386109 Я хочу знать правильный подход, мой текущий подход неверен,   -  person Rajat Aggarwal    schedule 26.06.2020
comment
У вас правильный подход, даже-даже проигрышное состояние. Для ходов нужно посчитать, сколько ходов потребуется, чтобы все камни оказались справа. Например, с **. это два хода: **. -> *.* -> .**. С *.**.. это 7 ходов: *.**.. -> *.*.*. -> *.*..* -> *..*.* -> *...** -> .*..** -> ..*.** -> ...***   -  person user3386109    schedule 26.06.2020


Ответы (1)


У вас логическая проблема с вашим алгоритмом, исходя из вашей логики, тот, кто ходит первым, всегда побеждает. Допустим, у вас есть сетка 3х1, и у вас есть два камня, пусть массив будет следующим: {полный, полный, пустой}, теперь в этом случае первый человек, который сделает ход, всегда будет проигрывать, допустим, он ходит на справа он станет {полным, пустым, полным}, тогда второй игрок переместит другой камень вправо, {пустой, полный, полный}, и тогда у него не будет другого выбора, кроме как убрать камень, а второй игрок уберет другой камень, приводящий к массиву finally: {пусто, пусто, пусто}, следовательно, первый игрок проигрывает, если вместо этого первый игрок уберет камень своим первым ходом, второй игрок уберет второй: снова приводит к { пустой, пустой, пустой} комбинация. Таким образом, вы не можете просто предположить, что игрок, который ходит первым, всегда побеждает.

спасибо, Юн Фей Чен

person Yunfei Chen    schedule 24.06.2020
comment
Что должны делать cnt&1 и pos&1, я никогда не видел эти символы, прежде чем просто сказать.... - person Yunfei Chen; 25.06.2020
comment