- Nim游戏
给定n堆物品,第i堆物品有Ai个。两名玩家轮流行动,每次可以任选-一堆,取走任意多个物品,可把一堆取光,但不能不取。取走最后一件物品者获胜。两人都采取最优策略,问先手能否必胜。
-
定理
NIM博弈先手必胜,当且仅当 A1 xorA2xor … xorAn ≠ 0。 -
Staircase Nim阶梯尼姆
向一个方向移动,最后不能走的就为输,根据数据总数n的奇偶性进行分堆,确定出Nim游戏中的Ai
相关例题
POJ 1704 Georgia and Bob
题目描述
佐治亚和鲍勃决定玩一个自己发明的游戏。他们在纸上画一排网格,将网格从左到右编号1,2,3,.并在不同的网格上放置N个棋子,例如,如下图所示:
佐治亚和鲍勃轮流移动棋子。每次玩家会选择一个棋子,然后把它移到左边,而不超过任何其他棋子,或者越过左边的边缘。玩家可以自由选择棋子移动的步骤数,限制棋子必须至少移动一步,而一个网格最多只能包含一个棋子。不能移动的玩家输掉了比赛。
自从“女士优先”之后,乔治亚一直是第一名。假设佐治亚和鲍勃在比赛中都尽了最大的努力,也就是说,如果他们中的一个知道赢得比赛的方法,他或她就能做到这一点。
考虑到棋手们最初的位置,你能预测谁将最终赢得这场比赛吗?
样例
样本输入
2
3
1 2 3
8
1 5 6 7 9 12 14 17
样本输出
Bob will win
Georgia will win
n为奇数时, 把奇数的分为一组, n为偶数时把偶数的分为一组,Ai 为每组两个数之间的距离
代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1010;
int a[N];
int n;
int main(){
int t;
cin >> t;
while(t--){
cin >> n;
int ans = 0;
for(int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + 1 + n);
if(n & 1){
for(int i = 1; i <= n; i += 2){
ans ^= a[i] - a[i - 1] - 1;
}
}
else{
for(int i = 2; i <= n; i += 2){
ans ^= a[i] - a[i - 1] - 1;
}
}
if(ans == 0)
cout << "Bob will win" << endl;
else cout << "Georgia will win" << endl;
}
return 0;
}