网址:http://codeforces.com/contest/1194/problem/D
题意:
有一个长度是$n+1$格的纸从左向右标记着$0,1,2,......,n$,有一个棋子在标记为$n$的格子,两个人轮流进行,一次可以向左移动$1,2,k$格,不能不移动,先移动到$0$的输,问谁会输。
题解:
尼姆博弈的一种,SG函数是$0$时先手败,以$nleq 30,kleq 30$打表可以发现规律,按照规律判断即可。
AC代码:
#include <bits/stdc++.h> using namespace std; int f[35],sg[35],hashing[35]; void getsg(int n,int size) { memset(sg,0,sizeof(sg)); for(int i=0;i<=n;++i)//总个数 { memset(hashing,0,sizeof(hashing)); for(int j=0;f[j]<=i&&j<size;++j) hashing[sg[i-f[j]]]=1;//可以到达的i的下一个状态 for(int j=0;j<=n;++j) { if(hashing[j]==0) { sg[i]=j; break; } } } } void gettable() { for(int i=3;i<=30;++i) { f[0]=1; f[1]=2; f[2]=i; for(int j=0;j<=30;++j) { cout<<"k="<<i<<" "<<"n="<<j<<endl; getsg(j,3); for(int k=0;k<=j;++k) cout<<sg[k]<<" "; cout<<endl; } } } void solve(int n,int k) { if(n==0) cout<<"Bob"<<endl; else if(k%3==0) { n%=(k+1); if(n==k) cout<<"Alice"<<endl; else if(n%3==0) cout<<"Bob"<<endl; else cout<<"Alice"<<endl; } else { if(n%3==0) cout<<"Bob"<<endl; else cout<<"Alice"<<endl; } } int main() { //gettable(); int n,a,b; cin>>n; while(n--) { cin>>a>>b; solve(a,b); } return 0; }