POJ 1704 Georgia and Bob(阶梯博弈)

题意:在一列上给你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;
}
原文地址:https://www.cnblogs.com/lalalatianlalu/p/9860733.html