备战蓝桥杯
菜鸟学习算法的第二天
相对于第一天,第二天对判题系统以及编码格式已经比较熟悉了。今天把入门题做完了,也有不少收获,主要写一下Fibonacci数列这道题。
问题描述
Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1。
当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少。
输入格式
输入包含一个整数n。
输出格式
输出一行,包含一个整数,表示Fn除以10007的余数。
样例输入
10
样例输出
55
样例输入
22
样例输出
7704
数据规模与约定
1 <= n <= 1,000,000。
看到此题,第一思路直接就是用数组存Fibonacci数列,然后直接对10007取余。但是存在溢出错误,所以不能采用此方法。
这道题关键要用到
余数的加法定理:
a与b的和除以c的余数,等于a,b分别除以c的余数之和用这个和除以c的余数。
即:(a+b)%c = (a%c+b%c)%c
例如:23,16除以5的余数分别是3和1,所以23+16=39除以5的余数等于4,即两个余数的和3+1.
当余数的和比除数大时,所求的余数等于余数之和再除以c的余数。
例如:23,19除以5的余数分别是3和4,故23+19=42除以5的余数等于3+4=7除以5的余数,即2.
知道这个定理之后就可以解决这道题了,用数组只存储Fibonacci数列的余数,这样避免了溢出问题,具体代码如下:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
int n = sc.nextInt();
int F[] = new int[1000000];
F[1]=F[2]=1;
for(int i =3 ; i<=n; i++)
{
F[i]=(F[i-1]+F[i-2])%10007;
}
System.out.println(F[n]);
}
}
对于Fibonacci数列问题,递归也是常用方法之一,通过递归求Fibonacci数,然后对10007取余,但是会运行超时,这里只是提一下递归思路,书写代码还应用第一种方法。
import java.util.Scanner;
public class Main{
public static void main(String args[])
{
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
System.out.println(F(n)%10007);
}
public static long F(int x){
if(x==1||x==2)
return 1;
else
return F(x-1)+F(x-2);
}
}
递归:“自己调用自己”,在这里主要用来调用F(n-1)和F(n-2),通过写递归函数实现求Fibonacci值。
今日小结:
(1)温习了一下递归思路,“自己调用自己”。
(2)今天有道格式化输出的题,第一下没有写出来,重新看了一下格式化输出:
printf方法常用格式说明符列表
%c 单个字符
%d 十进制整数
%f 十进制浮点数
%o 八进制数
%s 字符串
%u 无符号十进制数
%x 十六进制数
%% 输出百分号%
printf的常用格式控制:
% 0m.n格式字符
下面对组成格式说明的各项加以说明:
① % 格式说明的起始符号,不可缺少。
② 0 有0表示指定空位填0,如省略表示指定空位不填。
③ m.n m指域宽,即对应的输出项在输出设备上所占的字符数。n指精度。用于说明输出的实型数的小数位数。为指定n时,隐含的精度为n=6位。
(3)了解到了余数的加法定理:两个数的和对第三个数取余=前两个数分别对第三个数取余之后求和再对第三个数取余。
(4)蓝桥杯判题系统:每通过一个样例得10分,所以自己在编译器上测试时应测试多种情况。
来源:CSDN
作者:时代信念
链接:https://blog.csdn.net/Elon15/article/details/103985217