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 }

你可能感兴趣的:(body)