📌  相关文章
📜  N块石头游戏,每个玩家可以移除1、3或4

📅  最后修改于: 2021-05-04 12:30:57             🧑  作者: Mango

两名玩家正在玩n块石头,其中玩家1总是最先玩。两名玩家轮流交替移动并发挥出最佳状态。玩家只需一步即可从一堆石头中取出1、3或4个石头。如果玩家无法采取行动,那么该玩家将输掉比赛。给定n小于200的宝石数量,找到并打印获胜者的名字。

例子:

Input : 4
Output : player 1

Input : 7
Output : player 2

为了解决这个问题,我们需要找到n的每个可能值作为获胜或失败的位置。由于上述游戏是公正的组合游戏之一,因此输赢位置的表征是有效的。

获胜和失败状态的特征是:

  • 所有终端头寸均为亏损头寸。
  • 从每个获胜位置开始,至少有一个举动到失落位置。
  • 从每一个失败的位置,每一个举动都是一个获胜的位置。

如果玩家能够采取行动,使下一局成为失败状态,而不是处于获胜状态。找到玩家1的状态,如果玩家1处于获胜状态,则玩家1赢得游戏,否则玩家2将获胜。

考虑以下基本位置:

  1. 位置0是输球状态,如果石头数为0,则玩家1将无法移动,因此玩家1输了。
  2. 位置1是获胜状态,如果结石数目为1,则玩家1将移除结石并赢得比赛。
  3. 位置2是输球状态,如果石头的数目为2,则玩家1将移除1块石头,然后玩家2将移除第二块石头并赢得比赛。
  4. 位置3是获胜状态,如果玩家能够采取行动以使下一步成为失败状态(而不是处于获胜状态),则palyer1将移除所有3块宝石
  5. 位置4是获胜状态,如果玩家能够采取行动以使下一步成为失败状态(而不是处于获胜状态),则palyer1将移除所有4块宝石
  6. 位置5是获胜状态,如果玩家能够采取行动以使下一招成为失败状态,而不是玩家处于获胜状态,则palyer1将移除3块石头,剩下2块石头,这是失败状态
  7. 位置6是获胜状态,如果玩家能够采取行动以使下一招成为失败状态,而不是玩家处于获胜状态,则palyer1将移除4块石头,剩下2块石头,这是失败状态
  8. 位置7是输球状态,如果棋子数为7,则玩家1可以移出1、3或4个输石,所有这些都导致输球状态,因此玩家1将输球。

下面是上述方法的实现:

CPP
// CPP program to find winner of
// the game of N stones
#include 
using namespace std;
  
const int MAX = 200;
  
// finds the winning and losing
// states for the 200 stones.
void findStates(int position[])
{
    // 0 means losing state
    // 1 means winning state
    position[0] = 0;
    position[1] = 1;
    position[2] = 0;
    position[3] = 1;
    position[4] = 1;
    position[5] = 1;
    position[6] = 1;
    position[7] = 0;
  
    // find states for other positions
    for (int i = 8; i <= MAX; i++) {
        if (!position[i - 1] || !position[i - 3]
            || !position[i - 4])
            position[i] = 1;
        else
            position[i] = 0;
    }
}
  
// driver function
int main()
{
    int N = 100;
    int position[MAX] = { 0 };
  
    findStates(position);
  
    if (position[N] == 1)
        cout << "Player 1";
    else
        cout << "Player 2";
  
    return 0;
}


Java
// Java program for the variation
// in nim game
class GFG {
      
    static final int MAX = 200;
      
    // finds the winning and losing
    // states for the 200 stones.
    static void findStates(int position[])
    {
          
        // 0 means losing state
        // 1 means winning state
        position[0] = 0;
        position[1] = 1;
        position[2] = 0;
        position[3] = 1;
        position[4] = 1;
        position[5] = 1;
        position[6] = 1;
        position[7] = 0;
      
        // find states for other positions
        for (int i = 8; i < MAX; i++) {
              
            if (position[i - 1]!=1 || 
                    position[i - 3]!=1
                  || position[i - 4]!=1)
                position[i] = 1;
            else
                position[i] = 0;
        }
    }
      
    //Driver code
    public static void main (String[] args)
    {
          
        int N = 100;
        int position[]=new int[MAX];
      
        findStates(position);
      
        if (position[N] == 1)
            System.out.print("Player 1");
        else
            System.out.print("Player 2");
    }
}
  
// This code is contributed by Anant Agarwal.


Python3
# Python3 program to find winner of
# the game of N stones
  
MAX = 200
  
# finds the winning and losing
# states for the 200 stones.
def findStates(position):
  
    # 0 means losing state
    # 1 means winning state
    position[0] = 0;
    position[1] = 1;
    position[2] = 0;
    position[3] = 1;
    position[4] = 1;
    position[5] = 1;
    position[6] = 1;
    position[7] = 0
  
    # find states for other positions
    for i in range(8,MAX+1):
        if not(position[i - 1]) or not(position[i - 3]) or not(position[i - 4]):
            position[i] = 1;
        else:
            position[i] = 0;
      
#driver function
N = 100
position = [0] * (MAX+1)
  
findStates(position)
  
if (position[N] == 1):
        print("Player 1")
else:
        print("Player 2")
  
  
# This code is contributed by
# Smitha Dinesh Semwal


C#
// C# program for the variation
// in nim game
using System;
  
class GFG {
      
    static int MAX = 200;
      
    // finds the winning and losing
    // states for the 200 stones.
    static void findStates(int []position)
    {
          
        // 0 means losing state
        // 1 means winning state
        position[0] = 0;
        position[1] = 1;
        position[2] = 0;
        position[3] = 1;
        position[4] = 1;
        position[5] = 1;
        position[6] = 1;
        position[7] = 0;
      
        // find states for other positions
        for (int i = 8; i < MAX; i++)
        {
            if (position[i - 1] != 1
                  || position[i - 3] != 1
                   || position[i - 4]!=1)
                position[i] = 1;
            else
                position[i] = 0;
        }
    }
      
    // Driver code
    public static void Main ()
    {
        int N = 100;
        int []position = new int[MAX];
      
        findStates(position);
      
        if (position[N] == 1)
            Console.WriteLine("Player 1");
        else
            Console.WriteLine("Player 2");
    }
}
  
// This code is contributed by vt_m.


PHP


输出:

Player 2