poj 2234 matches game

来源:互联网 发布:ios手环推荐 知乎 编辑:程序博客网 时间:2024/05/02 02:25

Matches Game
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 8880 Accepted: 5129

Description

Here is a simple game. In this game, there are several piles of matches and two players. The two player play in turn. In each turn, one can choose a pile and take away arbitrary number of matches from the pile (Of course the number of matches, which is taken away, cannot be zero and cannot be larger than the number of matches in the chosen pile). If after a player’s turn, there is no match left, the player is the winner. Suppose that the two players are all very clear. Your job is to tell whether the player who plays first can win the game or not.

Input

The input consists of several lines, and in each line there is a test case. At the beginning of a line, there is an integer M (1 <= M <=20), which is the number of piles. Then comes M positive integers, which are not larger than 10000000. These M integers represent the number of matches in each pile.

Output

For each test case, output "Yes" in a single line, if the player who play first will win, otherwise output "No".

Sample Input

2 45 453 3 6 9

Sample Output

NoYes

Source

POJ Monthly,readchild
题目大意:

有若干堆火柴和两个玩家,两个玩家一轮轮玩,每一轮,一个玩家可以选择一堆,并从该堆中取走任意根火柴,(取走的火柴根数不能是0),如果一个玩家取完火柴后,没有火柴留下,那么这个玩家赢了。

先考虑最简单的情况:

1.如果游戏只有一堆火柴,那么玩家I通过取走所有的火柴而获胜。

2.一开始有两堆火柴,数量分别是N1,N2.

游戏的取胜并不在于N1,N2的具体值是多少,而取决他们是否相等。

若N1不等于N2,玩家1可以从大堆中取走火柴使得两堆火柴数相等,然后玩家1以后每次取得数量与玩家2的相等,最终获得胜利。

若N1=N2,玩家2每次取跟玩家1相同数量的火柴,最终获得胜利。

这样,两堆取子的获胜策略就找到了。

3.首先回忆一下,没有正整数都可以转化为相应的二进制数,例如:57(10) = 111001(2)。

于是我们可以认为每一堆火柴数有2的幂的子堆组成。这样没有57枚火柴的大堆就可以看成数量分别为2^5,2^4,2^3 ,2^0,的四个子堆组成。

先考虑各个堆大小为N1,N2,N3......Nk的取子游戏,全部转化为二进制:

N1 = as.......a2a1a0

N2 = bs.......b2b1b0

...

Nk = ms......m2m1m0

如果每一种大小的子堆数是偶数,我们就称之为平衡的,而对应位相加的是偶数的称为平衡位,否则称为非平衡位。因此取子游戏是平衡的,当且仅当

as+bs + ......+ms 是偶数

...

a1+b1 + ......+m1 是偶数

a0+b0 + ......+m0 是偶数

玩家1能在非平衡态中取胜,玩家2能在平衡态中取胜。具体就不再证明。

归根结底,取子游戏的关键在于游戏开始处于何种状态,得出此算法:

n堆火柴数量对应的n个二进制数,连续进行n-1次异或运算。若结果是非0,则说明存在非平衡位,玩家1获胜,否则,玩家2获胜。


源代码如下:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <set>#include <queue>using namespace std;int n,m,tmp;int main(){    while(~scanf("%d",&n)){    m = 0;    for(int i = 0; i < n; i++){       scanf("%d",&tmp);       m ^= tmp;    }    printf("%s\n",m?"Yes":"No");    }    return 0;}




0 0