Description
Alice have a friend Bob, they like play games very much, They like to play games is to grab the stone, this classic game they play much times, so today they intend to make the classic reproduction, playing an overnight grab stone, they are two people who like innovation, so this time they got a new game is played
a. There are N heap stones here.
b. Each time you can select stones that do not exceed M heap for any operation
c. They play game in turns and cannot do nothing
d. People who cannot move stones are losers
e. Alice first
Input
The first line is T(0 < T <= 1000) T is TestCase
Next line is N, M(0 < N, M <= 10000)
Next line follow N number P, P is the number of stones in the stone heap(0 < P <= 10000)
Output
Case #TestCase: winner
If Alice win output Alice, otherwise Bob
Sample Input
1
5 1
1 2 3 4 5
Sample Output
Case #1: Alice
知道了nimk博弈这个家伙之后,这题要有多水有多水,比赛是还想着什么巴什博弈+nim等操作,-_-||
欲学nimk博弈,必先了解一下nim博弈,nimk与nim最大的区别就在于nim是在是取一堆进行操作,而nimk是取k堆进行操作(怪不得+了个k)
所以和nim博弈时的异或后模2不同,这里是要模k+1的!!(取1堆时模2,取k堆时就模k+1喽)
我知道你们最想看的东西在这里:
const int MAXN = 10005;
int SG[MAXN];//需要处理的SG值数组
int XOR[MAXN];//储存每一个二进制位上的和
int xxx;//储存每一个SG值的临时变量
int num;//储存当前SG值有多少位的临时变量
int maxn;//储存最大的SG值位数
bool solve(int N,int M)//N表示SG数组的大小,从1到N,M表示每次可以取1到M堆
{
memset(XOR, 0, sizeof XOR);
maxn = -1;
for (int i = 1; i <= N; i++)
{
xxx = SG[i];
num = 0;
while (xxx)
{
XOR[num] += xxx&1;
num++;
xxx >>= 1;
}
maxn = max(maxn, num);
}
for (int i = 0; i < maxn; i++)
if (XOR[i] % (M + 1))
return true;//返回true表示先手必胜
return false;//返回false表示先手必败
}
wtf ?,上面的你们都懒得看,代码给你们:
//nimk博弈问题
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn = 10005;
int sg[maxn], eor[maxn];
int num, maxs, hy;
int max(int x, int y)
{
if(x >= y)
return x;
else
return y;
}
bool nimk(int n, int m)
{
memset(eor, 0, sizeof(eor));
maxs = -1;
for(int i = 1; i <= n; i++){
hy = sg[i];
num = 0;
while(hy){
eor[num] += hy&1;
num++;
hy >>= 1;
}
maxs = max(maxs, num);
}
for(int i = 0; i < maxs; i++){
if(eor[i] % (m+1))
return true;
}
return false;
}
int main()
{
int T;
cin >> T;
int cas = 1;
while(T--){
memset(sg, 0, sizeof(sg));
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; i++){
cin >> sg[i];
}
if(nimk(n, m)){
printf("Case #%d: Alice\n", cas);
}
else
printf("Case #%d: Bob\n", cas);
cas++;
}
return 0;
}