博弈。
很明显,每瓶巧克力豆不能看成单独的一堆,因为从一瓶中拿走一些后还要放一些到其他瓶里。
我们可以把每一颗巧克力豆当成一堆,这一堆的数量就是它到最后一个瓶子的距离。我们取走瓶子i中的一颗并放一颗到瓶子j里,就相当于从这一颗巧克力豆的堆拿剩n-j个。
这个方法真的好机智~~~
#include<cstdio>
#include<cstring>
int T;
int n,a[30],sg[30],s,ans;
bool tf[30];
void getsg()
{
sg[1]=0;
for(int i=2;i<30;i++)
{
memset(tf,0,sizeof(tf));
for(int j=1;j<i;j++)
{
for(int k=1;k<=j;k++)
tf[sg[j]^sg[k]]=1;
}
for(int j=0;;j++)
if(!tf[j])
{
sg[i]=j;
break;
}
}
}
int main()
{
scanf("%d",&T);
getsg();//暴力求sg
while(T--)
{
s=ans=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
for(int i=0;i<n;i++)
{
if(a[i]&1)//假如这个瓶子里有偶数个巧克力豆,异或完之后全都没了;奇数个就只要异或一次就好了
s^=sg[n-i];
}
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
for(int k=j;k<n;k++)
{
if((s^sg[n-i]^sg[n-j]^sg[n-k])==0)
{
ans++;
if(ans==1)
{
printf("%d %d %d\n",i,j,k);
}
}
}
}
}
if(ans==0)
{
puts("-1 -1 -1\n0");
continue;
}
printf("%d\n",ans);
}
}
大概是今年最后一题了吧。