链接:http://acm.hdu.edu.cn/showproblem.php?pid=3951
题意:有一圈n个的硬币, 两个玩家轮流取,每次他们可以取1 ~ K个连续硬币, 最后一个取完为胜;
思路: 面对一个可以一次拿完的局面先手必胜, 如果k=1 那么由N的奇偶性决定, 否则后手一定可以使下一个局面为对称的, 因此一定会赢;
View Code
1 #include<stdio.h> 2 int main() 3 { 4 int t; 5 int n,k; 6 int i; 7 scanf("%d",&t); 8 for(i=1;i<=t;i++) 9 { 10 scanf("%d%d",&n,&k); 11 if(k>=n) 12 printf("Case %d: first\n",i); 13 else 14 { 15 if(k==1) 16 { 17 if(n%2!=0) 18 printf("Case %d: first\n",i); 19 else 20 printf("Case %d: second\n",i); 21 } 22 else 23 printf("Case %d: second\n",i); 24 } 25 } 26 return 0; 27 }
对比HDU 3980 Paint Chain
链接:http://acm.hdu.edu.cn/showproblem.php?pid=3980
题意:有一圈 N 个的硬币, 两个玩家轮流取,每次他们可以取M个连续硬币, 最后一个不能取的为负;
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 T, Ca, N,M; 12 int sg[1005]; 13 int mex( int x ) 14 { 15 if( sg[x]!=-1 )return sg[x]; 16 bool re[1005]={0}; 17 for( int i=0; i<=x-M-i; ++i ){ 18 re[mex(i)^mex(x-M-i)]=1; 19 } 20 int i=0; 21 while( re[i] ) i++; 22 return sg[x]=i; 23 } 24 int main( ) 25 { 26 scanf("%d", &T ); 27 while( T -- ){ 28 memset( sg, -1, sizeof sg ); 29 printf("Case #%d: ", ++Ca ); 30 scanf( "%d%d", &N, &M ); 31 if(N<M){ 32 printf("abcdxyzk\n") ; 33 continue ; 34 } 35 if( M==1 ){ 36 if( N&1 ) printf("aekdycoin\n") ; 37 else printf("abcdxyzk\n") ; 38 continue; 39 } 40 if(!mex(N-M)) printf("aekdycoin\n") ; 41 else printf("abcdxyzk\n") ; 42 43 44 } 45 return 0; 46 }