问题描述:
Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1。
当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少。
资源限制:
时间限制:1.0s 内存限制:256.0MB
输入格式:
输入包含一个整数n。
输出格式:
输出一行,包含一个整数,表示Fn除以10007的余数。
样例输入:
10
样例输出:
55
样例输入:
22
样例输出:
7704
数据规模与约定:
1<=n<=1000000.
分析:
方法一:
定义一个数组长度为n的数组,把数组的第一位和第二位都设为1,再通过循环使数组从第三位开始的后一位等于前两位的合。
import java.util.Scanner;
public class Fibonacci {
public static void main(String[] args) {
long start=System.currentTimeMillis();
Scanner in =new Scanner(System.in);
int n=in.nextInt();
int[] arr=new int[n];
arr[0]=1;
if(n>1) {
arr[1]=1;
}
for(int i=2;i<arr.length;i++) {
arr[i]=arr[i-1]%10007+arr[i-2]%10007;
}
System.out.println(arr[n-1]%10007);
long end=System.currentTimeMillis(); //获取结束时间
System.out.println("程序运行时间: "+(end-start)/1000+"s");
}
}
方法二:
第二种方法用的是递归,从最上层递归下来,但是一旦运算的数字变大,递归算法的重复运算太多,因为算f(n-1)的时候要算f(n-3),算f(n-2)的时候还要算f(n-3),不符合题目的资源要求。
import java.util.Scanner;
public class Fibonacci1 {
public static void main(String[] args) {
long start=System.currentTimeMillis();
Scanner in =new Scanner(System.in);
int n=in.nextInt();
System.out.println(fbnc(n)%10007);
long end=System.currentTimeMillis(); //获取结束时间
System.out.println("程序运行时间: "+(end-start)/1000+"s");
}
public static int fbnc(int n){
if(n==1|n==2) {
return 1;
}
return fbnc(n-1)%10007+fbnc(n-2)%10007;
}
}
方法三:
通过循环加交换变量的值就能得出
import java.util.Scanner;
public class Fibonacci2 {
public static void main(String[] args) {
long start=System.currentTimeMillis();
Scanner in =new Scanner(System.in);
int n=in.nextInt();
System.out.println(fbnc(n)%10007);
long end=System.currentTimeMillis(); //获取结束时间
System.out.println("程序运行时间: "+(end-start)/1000+"s");
}
public static int fbnc(int n){
int[] result= {1,1};
if(n<=2) {
return result[n-1];
}
int first =1;
int second=1;
int fbnc=0;
for(int i=2;i<n;i++) {
fbnc =first+second;
first=second%10007;
second=fbnc%10007;
}
return fbnc;
}
}