给定一个包含 n 个元素的数组 A[]。有两个玩家 Alice 和 Bob。玩家可以从数组中选择任何元素并将其删除。如果移除所选元素后所有剩余元素的按位异或等于 0,则该玩家输了。这个问题是 nim-game 的变体。
注:每个玩家轮流玩游戏。如果两个玩家都发挥最佳,找出获胜者。爱丽丝首先开始游戏。如果数组中有一个元素,则将其值视为数组的 XOR。
例子 :
Input : A[] = {3, 3, 2}
Output : Winner = Bob
Explanation : Alice can select 2 and remove it that make XOR of array equals to zero also if Alice choose 3 to remove than Bob can choose any of 2/3 and finally Alice have to make his steps.
Input : A[] = {3, 3}
Output : Winner = Alice
Explanation : As XOR of array is already zero Alice can’t select any element to remove and hence Alice is winner.
让我们一步一步开始解决。我们总共有三个选项用于数组和这个游戏的异或。
- 数组的 XOR 已经为 0:在这种情况下,Alice 将无法移动,因此 Alice 是赢家。
- 数组的异或不为零:现在,在这种情况下,我们有两个选择,数组的大小要么是奇数,要么是偶数。
- 情况 A:如果数组大小为奇数,那么 Bob 肯定会赢得比赛。
- 情况 B:如果数组大小为偶数,那么 Alice 将赢得比赛。
上述结论可以借助数学归纳法得到证明。
让 A[] = {1} 即数组的大小为奇数且数组的 XOR 非零:在这种情况下,Alice 可以选择元素 1,然后 A[] 将变为空,因此数组的 XOR 可以被视为零。结果鲍勃成为赢家。
令数组大小为偶数且数组的异或非零。现在我们可以证明 Alice 总能找到一个要移除的元素,使得数组中剩余元素的 XOR 非零。
为了证明这一点,让我们从矛盾开始,即假设您应该选择剩余数组的 XOR 的任何元素必须为零。
所以,让 A1 Xor A2 Xor … An = X 并且 n 是偶数。
根据我们的矛盾假设,对于 1<= i <= n,Ai Xor X = 0。
计算所有X Xor Ai(即n个方程)的XOR,
在对所有 n 个方程进行 XOR 之后,我们有 X Xor X…Xor X (n-times) = 0 因为 N 是偶数。
现在,我们也有 A1 Xor A2 Xor.. An = 0 但我们知道 A1 Xor A2…Xor = X。这意味着我们在偶数大小的数组中至少有一个元素,这样在将其删除后,非-零。
令数组的大小为偶数且数组的异或非零。 Alice 不能移除元素 Ai 使得剩余数字的异或为零,因为这将使 Bob 获胜。现在,采取另一种情况,当剩余的 N?1 数的异或非零时。我们知道 N?1 是偶数,并且从归纳假设,我们可以说当前移动之后的位置将是 Bob 的获胜位置。因此,对于爱丽丝来说,这是一个失败的位置。
int res = 0;
for (int i = 1; i <= N; i++) {
res ^= a[i];
}
if (res == 0)
return "ALice";
if (N%2 == 0)
return "Alice";
else
return "Bob";
C++
// CPP to find nim-game winner
#include
using namespace std;
// function to find winner of NIM-game
string findWinner(int A[], int n)
{
int res = 0;
for (int i = 0; i < n; i++)
res ^= A[i];
// case when Alice is winner
if (res == 0 || n % 2 == 0)
return "Alice";
// when Bob is winner
else
return "Bob";
}
// driver program
int main()
{
int A[] = { 1, 4, 3, 5 };
int n = siseof(A) / sizeof(A[0]);
cout << "Winner = " << findWinner(A, n);
return 0;
}
Java
// Java to find nim-game winner
class GFG {
// function to find winner of NIM-game
static String findWinner(int A[], int n)
{
int res = 0;
for (int i = 0; i < n; i++)
res ^= A[i];
// case when Alice is winner
if (res == 0 || n % 2 == 0)
return "Alice";
// when Bob is winner
else
return "Bob";
}
//Driver code
public static void main (String[] args)
{
int A[] = { 1, 4, 3, 5 };
int n =A.length;
System.out.print("Winner = "
+ findWinner(A, n));
}
}
// This code is contributed by Anant Agarwal.
Python3
# Python3 program to find nim-game winner
# Function to find winner of NIM-game
def findWinner(A, n):
res = 0
for i in range(n):
res ^= A[i]
# case when Alice is winner
if (res == 0 or n % 2 == 0):
return "Alice"
# when Bob is winner
else:
return "Bob"
# Driver code
A = [ 1, 4, 3, 5 ]
n = len(A)
print("Winner = ", findWinner(A, n))
# This code is contributed by Anant Agarwal.
C#
// C# to find nim-game winner
using System;
class GFG {
// function to find winner of NIM-game
static String findWinner(int []A, int n)
{
int res = 0;
for (int i = 0; i < n; i++)
res ^= A[i];
// case when Alice is winner
if (res == 0 || n % 2 == 0)
return "Alice";
// when Bob is winner
else
return "Bob";
}
//Driver code
public static void Main ()
{
int []A = { 1, 4, 3, 5 };
int n =A.Length;
Console.WriteLine("Winner = "
+ findWinner(A, n));
}
}
// This code is contributed by vt_m.
PHP
Javascript
输出 :
Winner = Alice
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。