题意:两人轮流取石子,总共三堆石子数量分别为n,m,p,每次取石子只能取斐波拉契数字数量,在最优状态下谁先取完。
思路:很明显可以将每堆石子看成一个节点,因此答案为sg[n]^sg[m]^sg[m]的值如果为0,后手获胜,反之先手获胜。
因为大小只有1000,可以直接去推sg函数求解。
可恶的bug:判断语句中写成SG[n]^SG[m]^SG[p]!=0,!比^的优先级高,应该写成(SG[n]^SG[m]^SG[p])!=0。谨记!
#include <bits/stdc++.h> using namespace std; #define ll long long int f[100]; int SG[1010]; int vis[1010]; int main() { int m,n,p; f[1]=1; f[2]=1; int len=0; for(int i=3;i<100;i++) { f[i]=f[i-1]+f[i-2]; if(f[i]>1000) { len=i; break; } } //printf("%d\n",len); SG[0]=0; for(int i=1;i<=1000;i++) { memset(vis,0,sizeof(vis)); for(int j=2;j<len;j++) { if(f[j]<=i) { vis[SG[i-f[j]]]=1; } else { break; } } for(int j=0;;j++) { if(!vis[j]) { SG[i]=j; break; } } } while(scanf("%d%d%d",&n,&m,&p)!=EOF) { if(m==0&&n==0&&p==0) { break; } if((SG[n]^SG[m]^SG[p])!=0) { printf("Fibo\n"); } else { printf("Nacci\n"); } } }