题意:给定n个不同的数表示n个位置上有棋子,两个人轮流进行操作,不能操作的人输,每次可以选一个棋子然后向左移动至少一步并且不能越过别的棋子并且一个格子最多只能有一个棋子。判断先手能否必胜。
分析:阶梯博弈的基础题,这题的思路挺巧妙的,先将位置排下序,我们将棋子相邻的两个两两组成一对,对于每一对我们会知道如果前面那个棋子向前走多少步后面那个棋子也是可以走同样多的距离,那么我们要消除的就是它俩最初的距离,那么就是nim博弈啦。如果n为奇数那么我们将第一个数与位置0组成一对。
代码:
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<bitset>
#include<math.h>
#include<vector>
#include<string>
#include<stdio.h>
#include<cstring>
#include<iostream>
#include<algorithm>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int N=1005;
const int MAX=1000000100;
const int mod=100000000;
const int MOD1=1000000007;
const int MOD2=1000000009;
const double EPS=0.00000001;
typedef long long ll;
const ll MOD=998244353;
const int INF=1000000010;
const double pi=acos(-1.0);
typedef double db;
typedef unsigned long long ull;
int a[N];
int main()
{
int i,k,n,t,xo;
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
for (i=1;i<=n;i++) scanf("%d", &a[i]);
xo=0;a[0]=0;
sort(a+1,a+n+1);
if (n&1) k=1;
else k=2;
for (i=k;i<=n;i+=2)
xo^=a[i]-a[i-1]-1;
if (xo) printf("Georgia will win\n");
else printf("Bob will win\n");
}
return 0;
}