求高位时
算法分析:f(n)= (1/sqrt(5))*pow((1+sqrt(5))/2,n)- (1/sqrt(5))*pow((1-sqrt(5))/2,n);
这个题目就是用到这个公式,化简f(n)=n*log10((1+sqrt(5))/2)-log10(sqrt(5))+log10(1-((1-sqrt(5))/(1+sqrt(5)))^n)后面红色部分是无穷小量,可以省略。
于是f(n)=n*log10((1+sqrt(5))/2)-log10(sqrt(5));
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int a[30];
int main()
{
int i,n,ans1;
double ans,ans2;
a[0]=0;a[1]=1;
for(i=2;i<21;i++)
a[i]=a[i-1]+a[i-2];
while(scanf("%d",&n)!=EOF)
{
if(n<=20)
{
printf("%d\n",a[n]);
}
else
{
ans=n*log10(0.5+0.5*sqrt(5))-log10(sqrt(5));
ans1=ans; //转换成int
ans2=ans-ans1; //求小数位后面的
ans=pow(10.0,ans2);
ans1=ans*1000;
printf("%d\n",ans1);
}
}
return 0;
}
用矩阵时:
# include<stdio.h>
int a[4],b[4],c[4],d[1000000],q;
void fun(int n)
{
if(n==1)
return ; //到底层是开始返回
fun(n/2);
b[1]=(a[1]*a[1]+a[2]*a[3])%10000;
b[2]=(a[1]*a[2]+a[2]*a[4])%10000;
b[3]=(a[3]*a[1]+a[4]*a[3])%10000;
b[4]=(a[3]*a[2]+a[4]*a[4])%10000;
a[1]=b[1];
a[2]=b[2];
a[3]=b[3];
a[4]=b[4];
if(n%2!=0)
{
b[1]=(a[1]*c[1]+a[2]*c[3])%10000;
b[2]=(a[1]*c[2]+a[2]*c[4])%10000;
b[3]=(a[3]*c[1]+a[4]*c[3])%10000;
b[4]=(a[3]*c[2]+a[4]*c[4])%10000;
a[1]=b[1];
a[2]=b[2];
a[3]=b[3];
a[4]=b[4];
}
}
int main()
{
int n,i;
while(scanf("%d",&n))
{
if(n==-1)
break;
a[1]=c[1]=0;
a[2]=c[2]=1;
a[3]=c[3]=1;
a[4]=c[4]=1;
if(n==0)
{
printf("0\n");
continue;
}
if(n==1||n==2)
{
printf("1\n");
continue;
}
i=1;
fun(n);
printf("%d\n",a[3]);
}
return 0;
}