两名玩家正在玩n块石头,其中玩家1总是最先玩。两名玩家轮流交替移动并发挥出最佳状态。玩家只需一步即可从一堆石头中取出1、3或4个石头。如果玩家无法采取行动,那么该玩家将输掉比赛。给定n小于200的宝石数量,找到并打印获胜者的名字。
例子:
Input : 4
Output : player 1
Input : 7
Output : player 2
为了解决这个问题,我们需要找到n的每个可能值作为获胜或失败的位置。由于上述游戏是公正的组合游戏之一,因此输赢位置的表征是有效的。
获胜和失败状态的特征是:
- 所有终端头寸均为亏损头寸。
- 从每个获胜位置开始,至少有一个举动到失落位置。
- 从每一个失败的位置,每一个举动都是一个获胜的位置。
如果玩家能够采取行动,使下一局成为失败状态,而不是处于获胜状态。找到玩家1的状态,如果玩家1处于获胜状态,则玩家1赢得游戏,否则玩家2将获胜。
考虑以下基本位置:
- 位置0是输球状态,如果石头数为0,则玩家1将无法移动,因此玩家1输了。
- 位置1是获胜状态,如果结石数目为1,则玩家1将移除结石并赢得比赛。
- 位置2是输球状态,如果石头的数目为2,则玩家1将移除1块石头,然后玩家2将移除第二块石头并赢得比赛。
- 位置3是获胜状态,如果玩家能够采取行动以使下一步成为失败状态(而不是处于获胜状态),则palyer1将移除所有3块宝石
- 位置4是获胜状态,如果玩家能够采取行动以使下一步成为失败状态(而不是处于获胜状态),则palyer1将移除所有4块宝石
- 位置5是获胜状态,如果玩家能够采取行动以使下一招成为失败状态,而不是玩家处于获胜状态,则palyer1将移除3块石头,剩下2块石头,这是失败状态
- 位置6是获胜状态,如果玩家能够采取行动以使下一招成为失败状态,而不是玩家处于获胜状态,则palyer1将移除4块石头,剩下2块石头,这是失败状态
- 位置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