题意:两人玩游戏,有n个平面,每个平面ai个点,轮流画线,线不相交不重复;如果一个平面上画出三角形, 则该平面不能再画线,最后不能画线的人输。
方法:用SG定理求一个平面的SG值,然后去SG函数值找规律,最后各个平面异或可得答案
sg[i]=mex{sg[0]^sg[i-2],sg[1]^sg[i-3],...sg[i-2]^sg[0]},
就是添加一条线后,可以把点分为左右两边,讨论线的左右边(sg异或);由于是凸多边形,已经连线的两边顶点不能连线,否则必定输(再加1线即为三角形);
前面几个sg没 规律,150以后的是34为一循环。
#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
int sg[500];
void inint()
{
sg[0]=0;
sg[1]=0;
sg[2]=1;
sg[3]=1;
int vis[500]={0};
int i,j,k;
for(i=4;i<310;i++)
{
memset(vis,0,sizeof(vis));
for(j=0;j+2<=i;j++)
{
vis[sg[j]^sg[i-j-2]]=1;
}
for(j=0;;j++)
if(!vis[j])
{
sg[i]=j;
break;
}
}
}
int SG(int x)
{
if(x<300) return sg[x];
else
{
x=x-200;
x=x%34;
x+=200;
return sg[x];
}
}
int main()
{
int t,n,i,j,res,c;
memset(sg,0,sizeof(sg));
inint();
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
res=0;
for(i=1;i<=n;i++)
{
scanf("%d",&c);
res=res^SG(c);
}
if(res) puts("Carol");
else puts("Dave");
}
return 0;
}