Misere Nim LightOJ - 1253 (不一样的nim博弈)

Alice and Bob are playing game of Misère Nim. Misère Nim is a game playing on k piles of stones, each pile containing one or more stones. The players alternate turns and in each turn a player can select one of the piles and can remove as many stones from that pile unless the pile is empty. In each turn a player must remove at least one stone from any pile. Alice starts first. The player who removes the last stone loses the game.

Input

Input starts with an integer T (≤ 200), denoting the number of test cases.

Each case starts with a line containing an integer k (1 ≤ k ≤ 100). The next line contains k space separated integers denoting the number of stones in each pile. The number of stones in a pile lies in the range [1, 109].

Output

For each case, print the case number and 'Alice' if Alice wins otherwise print 'Bob'.

Sample Input

3

4

2 3 4 5

5

1 1 2 4 10

1

1

Sample Output

Case 1: Bob

Case 2: Alice

Case 3: Bob


题意:给你若干堆石子,每次可以从任意一堆中挑选出来任意个,取最后一枚石子的人输;

思路:一般的nim博弈大家都会吧,一般的就是取最后一枚石子的人赢;

先讨论 n 堆石子全部为1的情况:

    当 n 为奇数时,先手一定输,后手一定赢

    当 n 为偶数时,先手一定赢,后手一定输;

当 n堆 不全部为1的情况:

    我们先看一般的nim博弈的必胜态:当前状态为必胜态,先手经最优策略 取过后,就到达必败态也就是平衡态,平衡态只能转移到不平衡态(必胜态),不平衡态经过 某一个途径 可以 转移到平衡态;

    当n堆 不全部为1时,当一般的nim博弈的必胜态也就是不一样的nim博弈的必胜态,当前状态为 不平衡态;

    先手                 后手             先手                              先手                     后手                          先手

   不平衡态 ---> 平衡态 ---> 不平衡态 ---> .........--> 不平衡态 ---> 不平衡态(下面有解释) --> 平衡态--> 

    必胜态            必败态          必胜态                          必胜态               必败态                 必胜态

    解释:在这些从 不平衡态 到 平衡态 的 转中,在不一样的nim博弈中,有一个临界情况,一定会出现 从不平衡态到不平衡态,后面这个不平衡态 是 (剩下奇数堆且这奇数堆石子数全部都是1),当前这个状态取的人一定输,也是就后手,所以先手一定赢;

代码:                                               

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define Max 110
int main()
{
	int i,j,t,n;
	scanf("%d",&t);
	j = 1;
	while(t--)
	{
		scanf("%d",&n);
		int flag = 0;
		int x,sum = 0;
		for(i = 0;i < n;i ++)
		{
			scanf("%d",&x);
			if(x != 1)
				flag = 1;
			sum ^= x; 
		}
		printf("Case %d: ",j);
		if(!flag)
		{
			if(n&1) printf("Bob\n");
			else printf("Alice\n");
		}
		else
		{
			if(sum) printf("Alice\n");
			else printf("Bob\n");
		}
		j++;
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/obsorb_knowledge/article/details/80671089
Nim