题目大意:在一个正整数数轴上,放着一些棋子,两人博弈,
每个人可以选取任意一个棋子,把它往左(与正方向相反)移动若干步,条件是移动过程中不能够经过另一些棋子。
问先手的必胜必败态;
关键在于模型转换,举个例子;
A----------------B---------------------C--------------------D
========〉
C左移
A----------------B-----C-------------------------------------D
相当于从BC中取出一些长度放到CD中,如果把它看成石子的话,就是从BC中取了一些石子给CD。
所以可以把n个棋子转化为 n-1段长度,长度可以看成棋子个数:
那么问题楼梯nim:
这是一个在n级台阶上进行的游戏,每级台阶上有一定数量的硬币。
第i级台阶上硬币的数目为 xi 。
参与游戏的两名玩家轮流执行如下操作:选择一个台阶i,并把第i级台阶上的若干枚硬币移动到第i-1级台阶上。
第0级台阶是地面,落在这上面的硬币将被清除。把最后一枚硬币移动到地面上的玩家获胜。
这个问题中,偶数台阶上的棋子是没有用的,
因为如果把偶数台阶上的棋子放到奇数台阶上, 对该奇数台阶以后的操作没有影响,因为在对于该奇数台阶进行操作时,
可以“顺便”把这些从上一级偶数台阶上流下来的棋子放到下一级偶数台阶,直到别放到0台阶,所以,把棋子放到偶数台阶上,就等于扔掉了。
于是就变成了奇数台阶上的取石子游戏,xor一下奇数台阶上的石子数即可。
program lmd;
var
t,ans,i,n,x,maxn:longint;
a,b:array[0..1000]of longint;
procedure sort(l,r:longint);
var i,j,x,z:longint;
begin
i:=l;j:=r;x:=a[(l + r)shr 1];
repeat
while a[i] < x do inc(i);
while a[j] > x do dec(j);
if i <= j then
begin
z:=a[i]; a[i]:=a[j]; a[j]:=z;
inc(i); dec(j);
end;
until i > j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end;
begin
assign(input,'1704.in');
assign(output,'1704.out');
reset(input);rewrite(output);
read(t);
for t:=1 to t do
begin
ans:=0; maxn:=0;
read(n);
for i:=1 to n do read(a[i]);
sort(1,n);
for i:=1 to n do b[i]:=a[i]-a[i-1]-1;
for i:=n downto 1 do
if (n-i)and 1=0 then
ans:=ans xor b[i];
if ans=0 then writeln('Bob will win')
else writeln('Georgia will win');
end;
close(input);close(output);
end.