题意:在一列上给你n个棋子,每个棋子可以向左移动多步,中间不能越过其他棋子,问最后谁赢了
思路:我们先将棋子两两分组,相邻的两个为一组,如果棋子数目为奇数时,第一颗棋子和左边界分组,为什么分组呢,因为组内的移动时候相对的,如果你要打破分组,肯定不是最优态,假设你现在处于N态,然后对手移动了一步,你只能保证一组中的相对位移不变,这个时候你才可以维护N态,所以根据SG的原理分为n/2个游戏
然后对每个游戏做Nim博弈没最后就得到结果了
代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; inline LL read() { LL x=0,f=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } const int maxn=1e3+7; int a[maxn]; int main() { int T=read(); while(T--){ int n=read(); for(int i=1;i<=n;i++)a[i]=read(); sort(a+1,a+1+n); a[0]=0; int ans=0; for(int i=n;i>0;i-=2){ ans^=(a[i]-a[i-1]-1); } if(ans)puts("Georgia will win"); else puts("Bob will win"); } return 0; }