两个玩家正在玩一个有 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是获胜状态,如果玩家能够采取移动使得下一步是失败状态而不是玩家处于获胜状态,则玩家 1 将移除所有 3 个石头
- 位置 4是获胜状态,如果玩家能够采取移动使得下一步是失败状态而不是玩家处于获胜状态,则玩家 1 将移除所有 4 个石头
- 位置 5是获胜状态,如果玩家能够采取行动使得下一步是失败的状态而不是玩家处于获胜状态,则玩家 1 将移除 3 个石头,留下 2 个石头,这是失败的状态
- 位置 6是获胜状态,如果玩家能够采取行动使得下一步是失败状态而不是玩家处于获胜状态,则播放器 1 将移除 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
Javascript
输出:
Player 2
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。