POJ 2234 Matches Game(Nim博弈裸题)

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

Nim博弈裸题,所有堆的值异或得0则先手输,否则先手赢。

Nim博弈及异或理解可看百度百科

这游戏看上去有点复杂,先从简单情况开始研究吧。如果轮到你的时候,只剩下一堆石子,那么此时的必胜策略肯定是把这堆石子全部拿完一颗也不给对手剩,然后对手就输了。
如果剩下两堆不相等的石子,必胜策略是通过取多的一堆的石子将两堆石子变得相等,以后如果对手在某一堆里拿若干颗,你就可以在另一堆中拿同样多的颗数,直至胜利。
如果你面对的是两堆相等的石子,那么此时你是没有任何必胜策略的,反而对手可以遵循上面的策略保证必胜。如果是三堆石子……

如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #include<vector>
 5 #include<cstring>
 6 #include<string>
 7 #include<algorithm>
 8 using namespace std;
 9 
10 
11 int main()
12 {
13     int n;
14     long long tmp,res;
15     while(~scanf("%d",&n))
16     {
17         scanf("%lld",&res);
18         for(int i=1;i<n;i++)
19         {
20             scanf("%lld",&tmp);
21             res ^=tmp;
22         }
23         if(res==0)
24             printf("No
");
25         else 
26             printf("Yes
");
27     }
28     return 0;
29 }


原文地址:https://www.cnblogs.com/Annetree/p/7181892.html