Codeforces Round #334 (Div. 1) C - Lieges of Legendre

C - Lieges of Legendre

题目大意:有n堆石子,每堆ai个,每次可以选择其中一堆拿掉一个,或者选一个数量为2 * x的堆将它变成k堆x个。

问你先手胜还是后手胜。

 

思路:显然要用sg函数,k为偶数的情况比较简单,看表可以直接得到答案,k为奇数的情况下需要求一下sg,

小数据需要特判一下。 

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int,int>
#define piii pair<int, pair<int,int> >

using namespace std;

const int N = 2e5 + 10;
const int M = 10 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-6;

int n, k;

int getSg(int x) {
    if(x == 0) return 0;
    if(!k) {
        if(x == 1) return 1;
        if(x == 2) return 2;
        if(x & 1) return 0;
        if(!(x & 1)) return 1;
    } else {
        if(x == 1 || x == 3) return 1;
        if(x & 1) return 0;
        int vis[3]; memset(vis, 0, sizeof(vis));
        vis[getSg(x - 1)] = true;
        vis[getSg(x / 2)] = true;
        for(int i = 0; ; i++)
            if(!vis[i]) return i;
    }
}

int main() {
    scanf("%d%d", &n, &k);
    k = k & 1;

    int ans = 0;
    for(int i = 1; i <= n; i++) {
        int x; scanf("%d", &x);
        ans ^= getSg(x);
    }

    if(ans) puts("Kevin");
    else puts("Nicky");
    return 0;
}
/*
*/

 

posted @ 2018-06-05 16:23  NotNight  阅读(158)  评论(0编辑  收藏  举报