HDU_1021:Fibonacci Again
2015-04-09 21:55 星星之火✨🔥 阅读(249) 评论(0) 收藏 举报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.
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为底的指数增长。指数可是会爆炸的啊:~