资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1。
当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少。
输入格式
输入包含一个整数n。
输出格式
输出一行,包含一个整数,表示Fn除以10007的余数。
说明:在本题中,答案是要求Fn除以10007的余数,因此我们只要能算出这个余数即可,而不需要先计算出Fn的准确值,再将计算的结果除以10007取余数,直接计算余数往往比先算出原数再取余简单。 |
---|
样例输入
10
样例输出
55
样例输入
22
样例输出
7704
数据规模与约定
1 <= n <= 1,000,000。
注意:
1.方法上:不能使用递归,造成超时
2.逻辑上,不能使用第三个参数d专门用来计算a+b的数,用c=a+b;c=(a+b)%10007;a=b,b=c
(我并不太懂当还没取到n时,c此时是取模数,拿它当b,对吗?)
代码进程:
代码1:❌
- 使用递归:超时
#include<bits/stdc++.h>
using namespace std;
int Fib(int n){
if(n==1 || n==2){
return 1;
}
else{
return Fib(n-1)+Fib(n-2);
}
}
int main(){
int n;
scanf("%d",&n);
printf("%d",Fib(n)%10007);
return 0;
}
代码2:❌
- 逻辑上:求出数,再去求模
int main(){
//求出数,再去求模
int n;
int a,b;
a=b=1;
scanf("%d",&n);
int c=0;
if(n==1 || n==2){
printf("1");
return 0;
}
for(int i = 3; i <= n; i++){
c=a+b;
a=b;
b=c;
}
printf("%d",c%10007);
return 0;
}
改进:
c=(a+b)%10007;
就对了
代码3:❌
- 确定第三个数,来循环再取模;c、d是区分的
int main(){
//将最终取模的数加以判断
int n;
scanf("%d",&n);
int a,b;//a为F(n-2);b为F(n-1)
a=b=1;
int c=0;//c为模
int d=0;
if(n==1 || n==2){
printf("1");
return 0;
}
for(int i = 3; i <= n; i++){
d = a+b;
if(d<10007){
c=d;
}else{
c=d%10007;
}
a=b;
b=d;
}
printf("%d",c);
return 0;
}
代码4:✔
int main(){
int n;
scanf("%d",&n);
int a,b;//a为F(n-2);b为F(n-1)
a=b=1;
int c=0;//c为模
if(n==1 || n==2){
printf("1");
return 0;
}
for(int i = 3; i <= n; i++){
if(a+b<10007){
c=a+b;
}else{
c=(a+b)%10007;
}
a=b;
b=c;
}
printf("%d",c);
return 0;
}
注意:
- 不能用递归!
c=(a+b)%10007; b=c
疑问:
逻辑上,不能使用第三个参数d专门用来计算a+b的数,用c=a+b;c=(a+b)%10007;a=b,b=c
(我并不太懂当还没取到n时,c此时是取模数,拿它当b,对吗?)