给定两个整数A和B ,并假设 Alice 和 Bob 正在玩一个游戏,从一个包含N 个球的袋子开始,其中,在一次移动中,玩家可以移除范围[A, B]之间的任意数量的球如果玩家不能移除任何球,那么玩家输了,如果爱丽丝和鲍勃交替进行游戏并且爱丽丝开始游戏,则任务是找到游戏的赢家。
例子:
Input: N = 2, A = 1, B = 1
Output: Bob
Explanation:
One way in which the game can be played is:
- Alice removes 1 ball, so the remaining balls are 1.
- Now, Bob removes the last ball.
- Alice cannot remove any balls, so she loses.
Input: N = 3, A = 1, B = 2
Output: Bob
朴素的方法:最简单的方法是找到每个状态的 grundy 数,并使用 Sprague – Grundy 定理找到获胜和失败的状态。
时间复杂度: O(N*N!)
辅助空间: O(N)
高效的方法:上述方法可以基于以下观察进行优化:
- Firstly, it can be observed that (A + B) is always losing state, because whatever X (A ≤ X ≤ B) number of balls the current player chooses, the opponent can always empty the bag as there will be (A + B – X) number of balls left where A ≤ (A + B – X) ≤ B.
- Also, from previous observations, one can observe that, for any multiple of (A + B) say, m*(A + B), the opponent can always reduce the current player to a state of (m – 1)*(A + B) and from (m – 1)*(A + B) to (m – 2)*(A + B) and so on.
- Thus, extending the above observation, one can say that for any multiple of (A + B), the opponent can always reduce the current player to a state of exactly (A + B), which is indeed a losing state. Therefore, all multiples of (A + B) are a losing state.
- So, the optimal choice for any player is to reduce the opponent to a multiple of (A + B), because after this, the player can always win, no matter what the opponent’s moves are.
- So, now losing states are the states from which one can never reduce the opponent to a multiple of (A + B).
- Therefore, any player with the state of the form: ((A + B)*m + y), where (0 ≤ y ≤ A-1) can never force the opponent to reduce to a multiple of (A + B), as any player can only pick at least A and at most B number of balls.
请按照以下步骤解决问题:
- 如果N%(A+B)小于A,则打印“ Bob ”。
- 否则,打印“ Alice ”。
下面是上述方法的实现:
C++
// C++ program of the above approach
#include
using namespace std;
// Function to find the winner of the
// game
string NimGame(int N, int A, int B)
{
// Stores sum of A and B
int sum = A + B;
// If N is of the form
// m*(A+B)+y
if (N % sum <= A - 1)
return "Bob";
// Otherwise,
else
return "Alice";
}
// Driver code
int main()
{
// Input
int N = 3, A = 1, B = 2;
// Function call
cout << NimGame(N, A, B) << endl;
return 0;
}
Java
// Java Program for the above approach
import java.io.*;
class GFG
{
// Function to find the winner of the
// game
public static String NimGame(int N, int A, int B)
{
// Stores sum of A and B
int sum = A + B;
// If N is of the form
// m*(A+B)+y
if (N % sum <= A - 1)
return "Bob";
// Otherwise,
else
return "Alice";
}
public static void main (String[] args)
{
// Input
int N = 3, A = 1, B = 2;
// Function call
System.out.println(NimGame(N, A, B));
}
}
// This code is contributed by Potta Lokesh
Python3
# Python3 program of the above approach
# Function to find the winner of the game
def NimGame(N, A, B):
# Stores sum of A and B
sum = A + B
# If N is of the form
# m*(A+B)+y
if (N % sum <= A - 1):
return "Bob"
# Otherwise,
else:
return "Alice"
# Driver code
# Input
N = 3
A = 1
B = 2
# Function call
print(NimGame(N, A, B))
# This code is contributed by amreshkumar3
C#
// C# program of the above approach
using System;
class GFG{
// Function to find the winner of the
// game
public static String NimGame(int N, int A, int B)
{
// Stores sum of A and B
int sum = A + B;
// If N is of the form
// m*(A+B)+y
if (N % sum <= A - 1)
return "Bob";
// Otherwise,
else
return "Alice";
}
// Driver code
static void Main()
{
// Input
int N = 3, A = 1, B = 2;
// Function call
Console.Write(NimGame(N, A, B));
}
}
// This code is contributed by SoumikMondal
Javascript
输出
Bob
时间复杂度: O(1)
辅助空间: O(1)