[POJ 2315] Football Game

一、题目

点此看题

二、解法

先把题设做一个转化,有 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");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值