Problem Description
There are another kind of Fibonacci numbers: F(0) = 7, F(1) = 11, F(n) = F(n-1) + F(n-2) (n>=2).
Input
Input consists of a sequence of lines, each containing an integer n. (n < 1,000,000).
Output
Print the word "yes" if 3 divide evenly into F(n).
Print the word "no" if not.
Sample Input
0
1
2
3
4
5
Sample Output
no no yes no no no
本题类似于HDU_1005:Number Sequence,算是其简化版。根据其思想,我们可以求F(n) = [F(n-1) + F(n-2)] mod 3。容易知道,数列的每项只能在0, 1, 2三个中间取值,因此组合数是9,由鸽巢原理,在10个组合情况中至少出现两对对应相等。换句话说,数列的循环周期至多是9。
可以手算出循环周期,当然亦可以写一个程序来算一下:
#include<stdio.h> int main(void) { int f0 = 7, f1 = 11, j = 0; int a[10]; for(int i = 0; i < 10; i++) { a[j] = (f0+f1)%3; f0 = f1; f1 = a[j++]; } for(int i = 0; i < 10; i++) printf("%d ", a[i]); return 0; }
输出结果:0 2 2 1 0 1 1 2 0 2。容易看出,循环周期为8,而从第一个数起每隔三个数0便出现一次。
因此,容易写出以下代码:
#include<stdio.h> int main(void) { int n; while(scanf("%d", &n) != EOF) { if((n-2)%4 == 0) printf("yes\n"); else printf("no\n"); } return 0; }
当然,与HDU_1005不同的是,本题的数列的每项是确定的,因此可以打表通过:
#include<stdio.h> #define MAXN 1000000 int a[MAXN+10]; int main(void) { a[0] = 7; a[1] = 11; int n; for(int i = 2; i <= 1000000; i++) { a[i] = (a[i-1] + a[i-2]) % 3; } while(scanf("%d", &n) != EOF) { if(a[n] == 0) printf("yes\n"); else printf("no\n"); } return 0; }
或许HDOJ系统测试强度不够吧,这题暴力破解都可以通过:
#include<stdio.h> int main(void) { int f0 = 7, f1 = 11, j = 0, f2; int a[10]; int n; while(scanf("%d", &n) != EOF) { f0 = 7; f1 = 11; for(int i = 2; i <= n; i++) { f2 = (f0 + f1) % 3; f0 = f1; f1 = f2; } if(n == 0 || n == 1) printf("no\n"); else if(f2 == 0) printf("yes\n"); else printf("no\n"); } return 0; }
另外,打表的时候要注意,该题不mod3的话,也就是直接存入每项的具体值,然后直接取出求模的方式是不可取的,因为对于1, 1开头的斐波那契数列的第四十余项int类型已经存不下了(可以写个程序测试),这是因为斐波那契数列以接近0.618为底的指数增长。指数可是会爆炸的啊:~