B - Nim--尼姆博弈

Nim is a 2-player game featuring several piles of stones. Players alternate turns, and on his/her turn, a player’s move consists of removing one or more stones from any single pile. Play ends when all the stones have been removed, at which point the last player to have moved is declared the winner. Given a position in Nim, your task is to determine how many winning moves there are in that position.

A position in Nim is called “losing” if the first player to move from that position would lose if both sides played perfectly. A “winning move,” then, is a move that leaves the game in a losing position. There is a famous theorem that classifies all losing positions. Suppose a Nim position contains n piles having k1, k2, …, kn stones respectively; in such a position, there are k1 + k2 + … + knpossible moves. We write each ki in binary (base 2). Then, the Nim position is losing if and only if, among all the ki’s, there are an even number of 1’s in each digit position. In other words, the Nim position is losing if and only if the xor of the ki’s is 0.

Consider the position with three piles given by k1 = 7, k2 = 11, and k3 = 13. In binary, these values are as follows:

 111
1011
1101
 

There are an odd number of 1’s among the rightmost digits, so this position is not losing. However, suppose k3 were changed to be 12. Then, there would be exactly two 1’s in each digit position, and thus, the Nim position would become losing. Since a winning move is any move that leaves the game in a losing position, it follows that removing one stone from the third pile is a winning move when k1 = 7, k2 = 11, and k3 = 13. In fact, there are exactly three winning moves from this position: namely removing one stone from any of the three piles.

Input

The input test file will contain multiple test cases, each of which begins with a line indicating the number of piles, 1 ≤ n ≤ 1000. On the next line, there are n positive integers, 1 ≤ ki ≤ 1, 000, 000, 000, indicating the number of stones in each pile. The end-of-file is marked by a test case with n = 0 and should not be processed.

Output

For each test case, write a single line with an integer indicating the number of winning moves from the given Nim position.

Sample Input

3
7 11 13
2
1000000000 1000000000
0

Sample Output

3
0

翻译如下:

Nim是一款2人游戏,拥有几堆石头。玩家轮流,在他/她的回合中,玩家的移动包括从任何一堆石头中移出一个或多个石头。游戏结束时,所有的石头都被移走,在这一点上,最后一个移动的玩家被宣布为赢家。给定Nim中的一个位置,您的任务是确定该位置中有多少个获胜移动。


在尼姆,如果双方都打得很好,第一个离开那个位置的人就会输,那么这个位置就叫做“输”。“胜利的一步”,就是让游戏处于一个失败的位置。有一个著名的定理可以分类所有亏损的头寸。假设一个Nim位置包含n个桩,分别为k1、k2、…、kn个石子;在这样的位置,有k1 + k2 +…+ kn可能的移动。我们将每个ki写成二进制(以2为底),那么,当且仅当所有的ki中,每个数字位置上都有偶数个1时,Nim的位置就会丢失。换句话说,当且仅当ki的xor为0时,Nim的位置就会丢失。


考虑k1 = 7、k2 = 11和k3 = 13给出的三个桩的位置。在二进制中,这些值如下:


111

1011

1101


在最右边的数字中有奇数个1,所以这个位置没有损失。但是,假设k3改变为12。那么,每个数字的位置正好有两个1,因此,Nim的位置就会丢失。因为一个胜利的移动是使游戏处于一个输的位置的任何移动,因此当k1 = 7, k2 = 11,和k3 = 13时,从第三堆移走一块石头就是一个胜利的移动。事实上,在这个位置上有三种获胜的走法:即从三堆石头中取出一块石头。


输入

输入测试文件将包含多个测试用例,每个始于一行表明桩的数量,1≤n≤1000。下一行,有n个正整数,1≤ki≤1,000,000,000,表明每个桩的石头。文件末尾由一个测试用例标记,n = 0,不应该被处理。


输出

对于每个测试用例,编写一行带有整数的代码,表示从给定的Nim位置开始的获胜移动数。

思路:

nim博弈

把每个分别一个个互相异或得到的再异或比较和原来的大小即可

代码如下:

#include<iostream>
#include<cstdio>
using namespace std;
long long a[100000];
int main()
{
	long long  n;
	while(1)
	{
		scanf("%lld",&n);
		if(n == 0)
		{
			break;
		}long long g=0;
		for(long long i=0;i<n;i++)
		{
			scanf("%lld",&a[i]);g=a[i]^g;
		}
		long long r=0;
		for(long long i=0;i<n;i++)
		{
			if((g^a[i]) < a[i])
			{
				r++;
			}
		}
		printf("%lld\n",r);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43568078/article/details/86496290