HDU 3032 Nim or not Nim?

取走-分割游戏
       这种游戏允许取走某些东西,然后将原来的一个游戏分成若干个相同的游戏。
       例1、Lasker’s Nim游戏:每一轮允许两种操作之一。(1)从一堆石子中取走任意多个(2)将一堆数量不少于2的石子分成都不为空的两堆。
      分析:很明显,g(0)=0,g(1)=1。

      状态2的后继有0,1和(1,1),它们的SG函数值分别是0,1和0,所以g(2)=2。状态3的后继有0,1,2和(1,2),它们的SG函数值分别是0,1,2和3,所以g(3)=4。

  状态4的后继有0,1,2,3,(1,3)和(2,2),它们的SG函数值分别是0,1,2,4,5和0,所以g(4)=3。在推一些,我们得到:我们推测:对于所有的k>=0,有g(4k+1)=4k+1;g(4k+2)=4k+2;g(4k+3)=4k+4;g(4k+4)=4k+3。
请自行证明。
     假设游戏初始时有3堆,分别有2、5和7颗石子。三堆的SG函数值分别是2、5和8,它们的Nim和等于15。所以要走到P状态,就要使得第三堆的SG值变成7,可以将第三堆分成按1和6分成两堆。

View Code
#include<iostream>
 #include<cstdio>
 #include<cstdlib>
 #include<algorithm>
 #include<cmath>
 #include<queue>
 #include<set>
 #include<map>
 #include<cstring>
 #include<vector>
 #include<string>
 #define LL long long
 using namespace std;
 
 int main(  )
 {
     int n,T;
     while( scanf( "%d",&T )==1 )
     {
         while( T-- )
         {
             int s = 0,m;
             scanf( "%d",&n );
             for( int i = 0 ; i < n ; i ++ )
             {
                 scanf( "%d",&m );
                 if( m % 4 == 0 ) s ^= ( m - 1 );
                 else if( m % 4 == 3 ) s ^= ( m + 1 );
                 else s ^= m;  
             }
             if( s != 0 ) puts( "Alice" );
             else puts( "Bob" );    
         }    
     }
     //system( "pause" );
     return 0;
 }
 

 

 

posted @ 2012-09-25 19:51  wutaoKeen  阅读(359)  评论(0编辑  收藏  举报