关闭

Gym 101147.A - The game of Osho(SG函数+二项展开)

283人阅读 评论(0) 收藏 举报
分类:

题意:m堆石子,每堆有对应一个(BiNi),表示这堆有Ni个石子,每次可以拿Bix个石子(1BxiNi),谁不能拿谁输,1和2轮流拿,两人足够机智,问谁必胜。

思路:首先分奇偶性讨论,显然在Bi为奇数的时候,我们容易得到,Ni为奇数和偶数时候,分别是先手必胜、后手必胜。sg分别是1和0。

  然后是Bi为偶数的时候,我们可以对Bi^x进行一个二项式展开,有两种展开,(B - 1 + 1),(B + 1 - 1),我们选择后者进行展开,那么,由于是(a-b)^x,奇偶性影响每一项的符号,会得到两种展开,B^x = K*(B+1) + 1 或B^x =K*(B+1) + B。

  令Ni=y*(B+1)+T(0<=T<=B),那么问题变成T个石子,每次可以拿1个或B个。由于T<=B,所以只有当T=B时先手有机会第一次拿B个,其他所有情况两个人都无法拿B个,当T < B时,T为奇则先手胜(sg=1),T为偶则后手胜(sg=0),T=B时两个后继状态分别是B-1和0。B-1考虑一下奇偶性就能知道sg值,然后是0的sg值。
  

#include <bits/stdc++.h>
using namespace std;

int main()
{
    freopen("powers.in", "r", stdin);
    int T;
    scanf("%d", &T);
    while(T--)
    {
        int G;
        scanf("%d", &G);
        int ans = 0;
        for(int i = 0; i < G; i++)
        {
            int b, n;
            scanf("%d%d", &b, &n);
            if(b & 1)
            {
                if(n & 1)   ans ^= 1;
                else ans ^= 0;
            }
            else
            {
                int mod = n % (b + 1);
                if(mod == b)
                {
                    if(b & 1)   ans  ^= 1;
                    else ans ^= 2;
                }
                else
                {
                    if(mod & 1) ans ^= 1;
                    else ans ^= 0;
                }
            }
        }
        printf("%d\n", ans == 0 ? 2 : 1);
    }
    return 0;
}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:12447次
    • 积分:1269
    • 等级:
    • 排名:千里之外
    • 原创:120篇
    • 转载:0篇
    • 译文:0篇
    • 评论:2条
    友情链接