您的位置:首页 > 其它

Codeforces Round #334 E. Lieges of Legendre (组合游戏)

2015-12-03 03:26 267 查看
题意:

给定n,k≤109,然后组合游戏的规则,不同的是只有2种操作

1.任选1堆拿走一个,2.选一个2x个数堆变成k堆x个的

问谁赢

分析:

只看第二种操作,发现k分奇偶

奇数的话sg(2x)=sg(x)⊕sg(x)⋯⊕sg(x)k times=sg(x)

偶数的话sg(2x)=sg(x)⊕sg(x)⋯⊕sg(x)k times=0

n,k这么大显然打表找规律了

根据这个打个表发现很有规律,除了前几项

k->odd
i :  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
sg:  0  1  0  1  2  0  2  0  1  0  1  0  1  0  1  0  2  0  1  0  2
k->even
i :   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
sg:  0  1  2  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1


k奇数是前5项没规律,然后后面的奇数项都是0,偶数项不是1就是2

k偶数前3项没规律,然后后面的奇数项都是1,偶数项都是0

证明也很简单,induction就好了

代码:

//
//  Created by TaoSama on 2015-12-02
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
#define pr(x) cout << #x << " = " << x << "  "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;

int n, k;

/*
0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
0  1  0  1  2  0  2  0  1  0  1  0  1  0  1  0  2  0  1  0  2

0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
0  1  2  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1
*/

int odd[5] = {0, 1, 0, 1, 2}, even[3] = {0, 1, 2};

int getSg(int x) {
if(k & 1) {
if(x < 5) return odd[x];
if(x & 1) return 0;
return getSg(x >> 1) == 1 ? 2 : 1;
} else {
if(x < 3) return even[x];
return (x & 1) ^ 1;
}
}

int main() {
#ifdef LOCAL
freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);
//  freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);

while(scanf("%d%d", &n, &k) == 2) {
int ans = 0;
for(int i = 1; i <= n; ++i) {
int x; scanf("%d", &x);
ans ^= getSg(x);
}
puts(ans ? "Kevin" : "Nicky");
}
return 0;
}

/*
int getSg(int x) {
if(k & 1) {
if(!x) return 0;
if(~sg[x]) return sg[x];
set<int> s;
s.insert(getSg(x - 1));
if(!(x & 1)) s.insert(getSg(x >> 1));
for(int i = 0; ; ++i) if(!s.count(i)) return sg[x] = i;
} else {
if(!x) return 0;
if(~sg[x]) return sg[x];
set<int> s;
s.insert(getSg(x - 1));
if(!(x & 1)) s.insert(0);
for(int i = 0; ; ++i) if(!s.count(i)) return sg[x] = i;
}
}
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  组合游戏