poj 2234 matches game

本文介绍了一种简单的两人轮流进行的火柴游戏,并详细解析了如何通过算法判断首位玩家是否能赢得游戏。核心思想是将各堆火柴数量转换为二进制表示并进行异或运算,以此来判断游戏初始状态的平衡性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Matches Game
Time Limit: 1000MS Memory Limit: 65536K
Total 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 45
3 3 6 9

Sample Output

No
Yes

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;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值