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的倍数,就必胜。

方法二:
简单的SG函数的运用:

#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 }