hdu 1850 Being a Good Boy in Spring Festival <nim博弈>

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1850

题意: nim博弈先手赢的方法数:

思路:通常的Nim游戏的定义是这样的:有若干堆石子,每堆石子的数量都是有限的,合法的移动是选择一堆石子并拿走若干颗(不能不拿),如果轮到某个人时所有的石子堆都已经被拿空了,则判负(因为他此刻没有任何合法的移动);

定义P-positionN-position,其中P代表PreviousN代表Next。直观的说,上一次move的人有必胜策略的局面是P-position,也就是后手可保证必胜或者先手必败,现在轮到move的人有必胜策略的局面是N-position,也就是先手可保证必胜更严谨的定义是:1.无法进行任何移动的局面(也就是terminal position)是P-position2.可以移动到P-position的局面是N-position3.所有移动都导致N-position的局面是P-position

对于一个Nim游戏的局面(a1,a2,...,an),它是P-position当且仅当sum(n)=a1^a2^...^an=0,其中^表示异或(xor)运算;所以当面对一个局面的时候,通过拿一堆石头中的某些使其sum=0即为胜利, sum(n-1)=k 表示前n-1 项的结果, 若an>=sum(n-1), 则表示an可以通过拿石头使其sum(n)=0;

View Code
 1 #include <iostream>
 2 #include <cmath>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <string>
 6 #include <stdlib.h>
 7 #include <algorithm>
 8 using namespace std;
 9 typedef long long LL;
10 const LL Mod= 1e9+7;
11 int a[105]; 
12 int main( )
13 {
14     int N;
15     while( scanf( "%d", &N )==1, N ){
16         int temp=0, ans=0;
17         for( int i=0; i<N; ++ i ){
18             scanf( "%d", &a[i] );
19             temp^=a[i];
20         }
21         if( temp==0 )puts( "0" );
22         else{
23             for( int i=0; i<N; ++ i )
24                 if( (a[i]^temp)<=a[i] )ans++;
25             printf( "%d\n", ans );
26         }
27     } 
28     return 0;
29 }

原文地址:https://www.cnblogs.com/jian1573/p/3050850.html