题目
题目描述
给定a0,a1,以及an=pa(n-1) + qa(n-2)中的p,q。这里n >= 2。 求第k个数对10000的模。
输入描述
输入包括5个整数:a0、a1、p、q、k。
输出描述:
第k个数a(k)对10000的模。
示例:
20 1 1 14 5
8359
思路:看到题目之后,我首先想到的是:递归,直接使用题目所给的公式,因为这个形式和斐波那契数列很神似,而后者是我学习递归的第一个案例,结果时间复杂度太高,没有通过。接着我就使用了递推的方法从前往后直接出结果。具体代码如下:
#include<bits/stdc++.h>
using namespace std;
int a0,a1,p,q,k;
int findk(int k){
if(k==0)
return a0%10000;
else if(k==1)
return a1%10000;
else
return (p*findk(k-1)+q*findk(k-2))%10000;
}
int main(){
cin>>a0>>a1>>p>>q>>k;
cout<<findk(k)%10000<<endl;
return 0;
}
// 递推方法
#include<bits/stdc++.h>
using namespace std;
int main(){
int a0,a1,p,q,k;
cin>>a0>>a1>>p>>q>>k;
if(k==0)
cout<<a0%10000;
else if(k==1)
cout<<a1%10000;
else{
int result=0;
//这部分是核心
for(int i=2;i<=k;i++){
result = (p*a1+q*a0)%10000;
a0 = a1;
a1 = result;
}
cout<<result%10000;
}
return 0;
}
结果:
两者之间时间复杂度分析
对于本题而言,第一种递归方法存在这许多的重复计算,如图2,在从上往下计算过程中,出现了大量的重复计算,相较之下,第二种 a2->a3->a4->…->an 的计算方式重复计算就少了许多。
接下来为了更为直观的表现这种差异,我们在原先程序中加入一个 num 变量统计每段程序运行的次数,结果如下:
从上图可见,仅仅是输出第五个元素,两种方法计算次数差距就已经很大了,当基数变大,n 变大之后,那它们的时间复杂度就更不可同日而语了。