新Fib数列
Time Limit: 2 Sec Memory Limit: 16 MB
Submit: 305 Solved: 199
[Submit][Status][Discuss]
Description
天地合,乃敢不君绝?我们发现求出斐波那契数列在某种意义下可以作为解决一些有意义问题的方法,特别是在模5意义下的某种组合,或许可以破解敌方的密码系统。出题人太懒了,对于算斐波那契数列这种难事,丌能找到简便方法,因此他就懒得丌想做了(即使想做可能要买上一条1PB的内存条)。他找到了善于思考、 用计算机快速解决问题的你!你能帮帮他吗?
斐波那契数列的定义为 F(n)=F(n-1)+F(n-2)。
Input
现有Q个询问, 每个询问都给出一个Qi。
对于每个询问
请你求出并输出斐波那契数列在模 5 意义下的第Qi项,每个询问的输出占一行。
Q<=10^6 Qi<=2*10^9
请留意本题数据范围。 本题共有25个测试点。
Output
如题
Sample Input
9
1 2 3 4 5 6 7 8 9
Sample Output
1
1
2
3
0
3
3
1
4
问题分析
对于这类后面的数据需要用到之前的数据一般都会去打表,但是对于,这道题,Qi最大可以取到2*10^9,显然用不了这么大的数组。但仔细想一想,新fib数列与普通的fib数列不同的是运算结果要模5,也就是说结果是0到4的数,那么根据取模加法运算的规律以及斐波拉切数列的定义,显然会有规律,也就是有重复的结果。
规律可以自己一个个列去找,还有一种方法是另外写代码打部分的表并输出,看出规律。
规律
打表,可以看出以20个为周期,所以我们只需要记录前20个数据的结果就可以了。
附:
#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e8;
int fib[N];
void make_list(int n){
fib[1]=fib[2]=1;
printf("(1)%d\t",fib[1]);
printf("(2)%d\t",fib[2]);
for(int i=3;i<=n;i+=2){
fib[i]=(fib[i-2]+fib[i-1])%5;
fib[i+1]=(fib[i-1]+fib[i])%5;
printf("(%d)%d\t",i,fib[i]);
printf("(%d)%d\t",i+1,fib[i+1]);
}
}
int main(){
make_list(100);
return 0;
}
代码如下
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
int n,i,q,fib[21];
fib[1]=fib[2]=1;
for(i=3;i<21;i++)
fib[i]=(fib[i-1]+fib[i-2])%5;
fib[0]=fib[20];
scanf("%d",&n);
while(n--)
{
scanf("%d",&q);
printf("%d\n",fib[q%20]);
}
return 0;
}