[HDU1848]Fibonacci again and again

来源:

ACM Short Term Exam_2007/12/13

题目大意:

Nim游戏的一个变形,给定三堆棋子,每次只能从其中一堆取,取的个数为Fibonacci数列中的任意一项。
思路:

首先递推求出Fibonacci数列的前1000项,然后构造SG函数$sg[i]=mex{sg[j]|j为i的后继状态}$。
答案即为三者SG函数的异或。

 1 #include<cstdio>
 2 #include<cctype>
 3 #include<cstring>
 4 inline int getint() {
 5     char ch;
 6     while(!isdigit(ch=getchar()));
 7     int x=ch^'0';
 8     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
 9     return x;
10 }
11 const int N=1001;
12 int f[N]={1,1},sg[N];
13 bool hash[N];
14 int main() {
15     for(int i=2;i<N;i++) f[i]=f[i-2]+f[i-1];
16     for(int i=1;i<N;i++) {
17         memset(hash,0,sizeof hash);
18         for(int j=1;f[j]<=i;j++) hash[sg[i-f[j]]]=true;
19         for(int j=0;j<N;j++) {
20             if(!hash[j]) {
21                 sg[i]=j;
22                 break;
23             }
24         }
25     }
26     for(int m=getint(),n=getint(),p=getint();m||n||p;m=getint(),n=getint(),p=getint()) {
27         puts(sg[m]^sg[n]^sg[p]?"Fibo":"Nacci");
28     }
29     return 0;
30 }
原文地址:https://www.cnblogs.com/skylee03/p/7356149.html