题目
https://vjudge.net/problem/POJ-2315
题意
有n堆石子,两个人轮流操作,每次最多取m次,最多在m堆里取
思路
1 一堆石头有 n 个,每次可以取 1~m 个的 sg 函数值 = sg[n] = n%(m+1)
2 XOR 又称半加运算,即只执行加法而不执行进位
nim博弈是只能在1堆里取,所以可以直接异或,即在二进制下异或,现在是m堆 所以要在(m+1)进制下异或
代码
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn = 2e5+100;
const double PI = acos(-1.0);
int a[50];
int sg[50];
int main()
{ios::sync_with_stdio(0);int n,m,l,r;while(scanf("%d%d%d%d",&n,&m,&l,&r) != EOF){int M = l / (2*PI*r);for(int i = 1;i <= n;i++){scanf("%d",&a[i]);a[i] = a[i] / (2*PI*r) + 1;sg[i] = a[i] % (M + 1);}int xxor[50];memset(xxor,0,sizeof(xxor));for(int i = 1;i <= n;i++){int top = 0;int x = sg[i];while(x){xxor[top++] += x%2;x /= 2;}}for(int i = 0;i <= 32;i++){if(xxor[i] % (m+1)){printf("Alice\n");break;}if(i == 32){printf("Bob\n");}}}return 0;
}