挑程上是这样说的:
把相邻的棋子两两组合转化成Nim游戏
比如棋子坐标为 : 1 3 7 10 18 27
那么看出有3堆石头分别有1,2,8个石头
其中1表示3可以移到2(可以拿走1个石头)
2表示10可以移到8,9(可以拿走1个或者2个石头)
8表示27可以移到19,20,21...26(有8种拿石头的方法)
可是这样看来只有每对里面的后者在移动,难道1,7,18不移动?
这样,如果7向左移动x格,必然可以使10往左移x格,这样直到左边的棋子无法移动
这样做相当于两个人都没有拿石头,但是当左边的石头无法再移动时
双方必然是按照Nim游戏的方式拿石头(移动棋子)
还有就是如果是奇数捏?
可以假设在0位置有一个石头就好
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<algorithm>
#define mem(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
int b[1003];
int main()
{
int T;cin>>T;
while (T--)
{
int n;cin>>n;
for (int i = 0;i < n;++i)
{
scanf("%d",&b[i]);
}
if (n&1)//奇数
{
b[n] = 0;
++n;
}
sort(b,b+n);
int s = 0;
for (int i = 0;i < n;i+=2)
{
s ^= (b[i+1]-b[i]-1);
}
if (s) puts("Georgia will win");
else puts("Bob will win");
}
return 0;
}
java:
//package acm.poj1704;
import java.util.*;
//博弈
public class Main {
static int b[] = new int [1111];
public static void main(String[] args) {
// TODO Auto-generated method stub
@SuppressWarnings("resource")
Scanner in = new Scanner (System.in);
int T = in.nextInt();
while ((T--)!=0){
int n = in.nextInt();
for (int i = 0;i < n;++i){
b[i] = in.nextInt();
}
if ((n&1)!=0){
b[n++] = 0;
}
Arrays.sort(b,0,n);
int s = 0;
for (int i = 0;i < n;i += 2){
s ^= (b[i+1]-b[i]-1);
}
if (s!=0)System.out.println("Georgia will win");
else System.out.println("Bob will win");
}
}
}