入门训练 Fibonacci数列
时间限制: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。
#include<stdio.h>
long long f(long long n)
{
if(n==1||n==2)return 1;
else return f(n-1)+f(n-2);
}
int main()
{
long long n;
scanf("%lld",&n);
printf("%lld\n",f(n)%10007);
return 0;
}
于是,出现了这样的结果:
那就是应该是大精度的问题了,明明学过数据结构会分析复杂度,却没有事先分析一下复杂度,造成了时间的浪费。大精度,整起!
下面是历史错误版本以及错误总结:
#include<stdio.h>
int main()
{
int f[1000005],n;
scanf("%d",&n);
f[0]==1;f[1]==1;
for(int i=2;i<=1000000:i++)
{
f[n]==(f[n-1]+f[n-2])%10007;
}
printf("%d\n",f[n]);
return 0;
}
1.f[0]==1;f[1]==1;
这里应该是赋值不是判断
2.for(int i=2;i<=1000000:i++)
分号打成冒号
3.f[n]==(f[n-1]+f[n-2])%10007;
变量不对,而且分号是中文全角(这里不知道为什么复制会出现高亮,加入代码块就好了)
#include<stdio.h>
int main()
{
int f[1000005],n,i;
scanf("%d",&n);
f[0]==1;f[1]==1;
for(i=2;i<=1000000:i++)
{
f[n]==(f[n-1]+f[n-2])%10007;
}
printf("%d\n",f[n]);
return 0;
}
仅修改了分号
#include<stdio.h>
int main()
{
int f[1000005],n,i;
scanf("%d",&n);
f[0]==1;f[1]==1;
for(i=2;i<=1000000;i++)
{
f[n]==(f[n-1]+f[n-2])%10007;
}
printf("%d\n",f[n]);
return 0;
}
for内的分号
#include<stdio.h>
int main()
{
int f[1000005],n,i;
scanf("%d",&n);
f[0]==1;f[1]==1;
for(i=2;i<=1000000;i++)
{
f[n]==(f[n-1]+f[n-2])%10007;
}
printf("%d\n",f[n]);
return 0;
}
这个好像交重了
#include<stdio.h>
int main()
{
int f[1000005],n,i;
scanf("%d",&n);
f[0]=1;f[1]=1;
for(i=2;i<=1000000;i++)
{
f[n]==(f[n-1]+f[n-2])%10007;
}
printf("%d\n",f[n-1]);
return 0;
}
修改了等号
#include<stdio.h>
int main()
{
int f[1000005],n,i;
scanf("%d",&n);
f[0]=1;f[1]=1;
for(i=2;i<=1000000;i++)
{
f[n]=(f[n-1]+f[n-2])%10007;
}
printf("%d\n",f[n-1]);
return 0;
}
for内的等号
当当当~
最终版本:
#include<stdio.h>
int main()
{
int f[1000005],n,i;
scanf("%d",&n);
f[0]=1;f[1]=1;
for(i=2;i<=1000000;i++)
{
f[i]=(f[i-1]+f[i-2])%10007;
}
printf("%d\n",f[n-1]);
return 0;
}
真是犯了好多初学c语言的时候才会犯的错误,太久不练了吧。反省反省orz
f[i]=(f[i-1]+f[i-2])%10007;
说实话,这一步挺巧妙的,其实不是我一开始自己想到的,是在其他人那里看到的,免得在最后输出时再算。
如果是一般的高精度题还不能这么算,刚好结果是在范围里的。
我们常常看到int取值范围为-32768~32767,实际上int的取值范围依赖于计算机系统,在16位机器中,int占16位,取值范围为前面所说的-32768~32767(-215~215-1)。而在32位和64位机器中,int占32位,取值范围为-2147483648~2147483647(-231~231-1)。ISO/ANSI C规定,int类型的最小范围为-32768到32767。