分析:第一次写博弈的题目,虽然这题比较简单。
如果 k 为偶数:
那么选择
sg(2x)⟶sg(x)⨂...⨂sg(x)
。一共
k
个
⟹sg(2x)⟶0
选择
1
操作后,该对能指向的状态是:
确定状态
sg(0)=0,sg(1)=1
。然后可知
sg(2x)=0
。
接着递归处理就行了,直接多写几个就能发现规律。
如果 k 为奇数:
那么选择
sg(2x)⟶sg(x)⨂...⨂sg(x)
。一共
k
个
⟹sg(2x)⟶sg(x)
选择
1
操作后,该对能指向的状态是:
确定状态
sg(0)=0,sg(1)=1
。当
x>=2
时然后可知
sg(2x+1)=0
。
接着递归处理就行了。
复杂度: o(nlog(a[i]))
附上代码:
#include <bits/stdc++.h>
#define LL long long
#define FOR(i,x,y) for(int i = x;i < y;++ i)
#define IFOR(i,x,y) for(int i = x;i > y;-- i)
using namespace std;
const int maxn = 100010;
int a[maxn],n,k;
int odd_sg(int x){
if(x == 0) return 0;
if(x == 1) return 1;
if(x == 2) return 0;
if(x == 3) return 1;
if(x % 2) return 0;
int t1 = odd_sg(x-1),t2 = odd_sg(x>>1);
FOR(i,0,4) if(i != t1 && i != t2) return i;
}
int main()
{
//freopen("test.in","r",stdin);
while(~scanf("%d%d",&n,&k)){
FOR(i,0,n) scanf("%d",&a[i]);
int ans = 0;
FOR(i,0,n){
int res;
if(k % 2 == 0){
if(a[i] == 1) res = 1;
else if(a[i] == 2) res = 2;
else res = 1-(a[i]%2);
}
else res = odd_sg(a[i]);
ans ^= res;
}
if(ans > 0) printf("Kevin\n");
else printf("Nicky\n");
}
return 0;
}