HDU 1847 Good Luck in CET-4 Everybody!

这也是一道巴什博弈;

这题如果你是先手,考虑你的必胜态。注意,因为任何正整数都能写成若干个2的整数次方幂之和。由于规定只能取2的某个整数次方幂,只要你留给对手的牌数为3的倍数时,那么你就必赢,因为留下3的倍数时,对手有两种情况:
1:如果轮到对方抓牌时只剩3张牌,对方要么取1张,要么取2张,剩下的你全取走,win!
2:如果轮到对方抓牌时还剩3*k张牌,对手不管取多少,剩下的牌数是3*x+1或者3*x+2。轮到你

 

时,你又可以构造一个3的倍数。 所以无论哪种情况,当你留给对手为3*k的时候,你是必胜的。
题目说Kiki先抓牌,那么当牌数为3的倍数时,Kiki就输了。否则Kiki就能利用先手优势将留给对方的牌数变成3的倍数,就必胜。

View Code
方法二:
简单的SG函数的运用:
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;
 void Get_SG( int num[], bool SG[] )
 {
      for( int i = 0; i <= 1000; i ++ )
           if( !SG[i] ){
                 for( int j = 0,t; j <= 10 && (t=i + num[j]) <= 1000; j ++ )
                 {
                      SG[t] = true;    
                 }
             }    
 }
 int main(  )
 {
     int num[11],n;
     bool SG[1024] = { 0 };
     for( int i = 0 ;i <= 10 ; i ++ )
          num[i] = 1<<i;
     Get_SG( num ,SG );
     while( scanf( "%d",&n )==1 )
     {
          if( SG[n] ) puts( "Kiki" );
          else puts( "Cici" );    
     }
     //system( "pause" );
     return 0;
 }
 

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 int main( )
 8 {
 9     int n;
10     while( scanf( "%d" ,&n )==1 )
11     {
12         puts( n%3==0?"Cici":"Kiki" );       
13     }
14     //system( "pause" );
15     return 0;
16 }
posted @ 2012-04-17 23:40  wutaoKeen  阅读(628)  评论(0)    收藏  举报