hdu 1850 Being a Good Boy in Spring Festival

链接: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 }

 

 

 

 

 

 

你可能感兴趣的:(spring)