链接:http://acm.hdu.edu.cn/showproblem.php?pid=4203
题意: 有一堆数量为 N 金币, 每次可以拿 M^x ( x=0,1,2,... )个,问先手如果能获胜, 第一次最少拿几块, 不能胜则输出0;
思路: sg打表找规律
sg=0则为必败点, sg=1, 只要拿1个就可以了, 如果sg=2, 那么就拿M个;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 sg[1000]; 12 int T, N, M; 13 int mex( int x )// sg 14 { 15 if( sg[x]!=-1 )return sg[x]; 16 bool re[1005]={0}; 17 int t=1; 18 while( 1 ){ 19 20 if(t>x)break; 21 re[mex(x-t)]=1; 22 t*=M; 23 } 24 int i=0; 25 while( re[i] )i++; 26 return sg[x]=i; 27 } 28 29 int main() 30 { 31 scanf("%d",&T); 32 for(int t=1;t<=T;t++){ 33 scanf("%d%d",&N,&M); 34 if(M&1){ 35 if(N&1)puts("1"); 36 else puts( "0" ); 37 } 38 else{ 39 int x=N%(M+1); 40 if(x==M)printf("%d\n",M); 41 else{ 42 if(x&1)puts( "1" ); 43 else puts("0"); 44 } 45 } 46 } 47 }