数组递归(涉及蓝桥杯2019C/C++A组一道题)
递归定义
在C/C++语言中,允许函数直接或间接调用自身——称为函数递归调用
递归怎么用
1.首先从一个事例判断出需要使用递归,比如数学中的递增增减函数,an
与an+1存在关系式,又比如根据一个函数判断出新的一项与上一项存在联系,可以从当前项不断更迭产生下一项,那么它就有可能存在递归的形式,如下两个式子
a n + 1 = a n a_{n+1}=a_n an+1=an
f ( n ) = { n ∗ f ( n − 1 ) , n>0 1 , n=0 f(n) = \begin{cases} n*f(n-1), & \text{n>0} \\ 1, & \text{n=0} \end{cases} f(n)={n∗f(n−1),1,n>0n=0
2.得出递归关系表达式
3.明确递归结束条件,不然无限递归下去。。。就。。。
递归实例
拿 f ( n ) = n ! f(n)=n! f(n)=n!来举例吧,它的结束条件是n==0,代码如下
#include <iostream>
using namespace std;
int fac(int n)
{
if (n == 0)
return 1;
else
return n * fac(n - 1);
}
int main()
{
int n;
cout << "n="; cin >> n;
cout << "f("<< n << "!)=" << fac(n) << endl;
}
常规思维(含蓝桥杯2019C/C++A组一道题)
先放出题目
给定数列1, 1, 1, 3, 5, 9, 17,…,从第4项开始,每项都是前3项的和。求第20190324项的最后4位数字。
看到题目很容易想到是递归,从第四项开始 a[n]=a[n-1]+a[n-2]+a[n-3] ,为了使代码简略,定义一个函数来运算递归内容,但本题要求的项数过大,会导致递归的次数过多,最终导致栈内存溢出,而且以我的方法也设置不了那么大的数组,所以这一段代码仅针对项数较小时的情况,我这是设置了求第14项的后四位数,具体代码如下
#include <iostream>
using namespace std;
int turn(int n)
{
long long a[1000] = { 0 };
a[0] = 1;
a[1] = 1;
a[2] = 1;
int i;
for (i = 3; i <=n; i++)
{
a[i] = a[i - 1] + a[i - 2]+a[i-3];
}
return a[i-2];
}
int main()
{
int n = 14;
int m=turn(n);
int b[4] = { 0 };
int num = 0;//用于计数
for (int j = 0;; j++)
{
b[num++] = m % 10;
m = m / 10;
if (m == 0)
break;
}
for (int k = num-1; k>=0; k--)
{
cout << b[k];
}
return 0;
}
方法改进
多加思考可以想到,因为题目仅要求给出最后四位数字,那么将每一次的结果对10000取余,可以得到每一次最后的四位数字,举个栗子,12457+324567=337024,最后四位数字为7024,而将12457和324567分别对10000取余,得到2457和4567,相加为7024,可以看到最终结果并不受影响,而数组中存放的是每一次结果的后四位数字,而且因为创建不了那么大的数组,故而我取消了数组去存放数据,转而用变量
修改后的代码如下
#include <iostream>
using namespace std;
int main()
{
int temp1 = 1,temp2 = 1,temp3=1;
int temp4 = 0;
for (int i = 4; i <=20190324; i++)
{
temp4 = (temp1 + temp2 + temp3)%10000;
temp1 = temp2;
temp2 = temp3;
temp3 = temp4;
}
cout << temp4;
}
最终结果
4659
简单了好多,还不用思考数组范围大小,此代码参考了原网址,并在此基础上以我自己的思维做了一部分修改。
以上均为学习笔记,若有错误,欢迎大家指出,一定积极讨论并予以改正