#解题原理我觉得不容易理解,有点归纳总结的味道,要先通过许多特殊情况来慢慢理清
#如果只有两堆,则可以得出如果两堆数量不等,先手赢,数量相等,后手赢。
#如果有奇数堆数量相等的堆,则先手赢(先手先去掉一堆,则剩下偶数堆),如果有偶数堆数量相等的堆,则后手赢。
#堆的个数和每堆拥有数量其实是我们人为分出来的,比如有n堆,每堆两个,我们也可以认为有一堆,堆里有2n个。
#通过以上几点叠加,我们这样理解:一堆的数量n,n在计算机为二进制储存,相当于已经划分出了2^0,2^1,2^2......这些数量的堆,比如6就是110(6有1个2^2的堆,1个2^1的堆),8就是1000(8有1个2^3的堆)。根据SG问题的一个原则,多个SG问题的值可以由多个SG值的连续异或(^)确定,故我们将6^8,就能得到总共的SG值。
#最后总结一句,n堆、不限定划去数量(当然不能大于选取堆的数量)的SG问题,直接将每堆数量异或运算就是所需求的SG值,SG值不为0则先手必赢,否则后手必赢。
#问题
Matches Game
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 11172 | Accepted: 6548 |
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
AC码
#include<iostream>
using namespace std;
int main()
{
int m;
int t;
while(cin>>m)
{
int ans=0;
while(m--)
{
cin>>t;
ans^=t;
}
if(ans)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
}