一、题目
二、解法
先把题设做一个转化,有 n n n堆石子,每次最多 m m m堆进行操作,最多取 k k k个,问先手有没有必胜策略。
首先考虑 m = 1 m=1 m=1的情况,每堆石子的 s g sg sg函数 = = =石子数 % \% %最大取走数 + 1 +1 +1
其他情况,我们把 s g sg sg函数写成二进制的形式,再对它们做 m + 1 m+1 m+1进制的不进位加法( m = 1 m=1 m=1是就是 x o r xor xor),最后得到的结果就是整个游戏的 s g sg sg函数,我们判断有没有位上有值即可。
至于证明,蒟蒻作者是真的不会,贴个代码吧。
#include <cstdio>
#include <cstring>
#include <cmath>
const int M = 105;
const double P = acos(-1.0);
int read()
{
int x=0,flag=1;char c;
while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*flag;
}
int n,m,l,r,a[M];
int dis(int s)
{
return (int)(s/(2*P*r))+1;
}
bool solve()
{
memset(a,0,sizeof a);
int k=dis(l);
for(int i=1;i<=n;i++)
{
int x=dis(read())%k;
for(int j=0;x;j++)
{
a[j]+=x&1;
x>>=1;
}
}
for(int i=0;i<30;i++)
if(a[i]%(m+1))
return 1;
return 0;
}
int main()
{
while(~scanf("%d %d %d %d",&n,&m,&l,&r))
{
if(solve()) puts("Alice");
else puts("Bob");
}
}