Fibonacci数列第n个数除以10007的余数

来源:互联网 发布:数据字典模板 编辑:程序博客网 时间:2024/05/19 05:05

问题描述:Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1。当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少。(1 <= n <= 1000000

开始的思路是直接利用递推公式算出第n个数,在求出余数。但不幸的是,得分没有得全。过后想了想,是由于当n过大时,Fn太大,基本的数据结构不能存储下,造成溢出,程序无法得出正确答案。

import java.util.Scanner;public class Main {public static void main(String[] args) {long f1=1;long f2=1;    long n;    long fn=0;    long i ;Scanner scanner=new Scanner(System.in);n=scanner.nextLong();if(n==1||n==2){fn=1;}for (i = 3; i <= n; i++) {fn=f1+f2;f1=f2;f2=fn;}System.out.println(fn%10007);}}


后来看了思路,取余运算中存在定理:(a + b) % p = (a % p + b % p) % p ,相当与分配率,一个数取p的余数,这个数可以看做a+b,则余数等于a取p的余数加上b取p的余数再对p取余数。而题目中的Fibonacci数列正好满足这一规则。我们只需要用一个数组保存每个Fn%10007的余数,求第n个余数就是求解(Fn-1%10007+Fn-2%10007)%10007。这样数组中保存的余数的最大值不会超过10007,完全不会溢出。


import java.util.Scanner;public class Main {public static void main(String[] args) {int n;final int num=10007;Scanner scanner =new Scanner(System.in);n=scanner.nextInt();if(n==1||n==2){System.out.println(1);}else {int[] a=new int[n];a[0]=1;a[1]=1;for(int i=2;i<n;i++){a[i]=(a[i-1]+a[i-2])%num;}System.out.println(a[n-1]);}}}


阅读全文
0 0
原创粉丝点击