洛谷【C++编程基础】递归函数初步专题解题报告-创新互联
题目描述
创新互联企业建站,十余年网站建设经验,专注于网站建设技术,精于网页设计,有多年建站和网站代运营经验,设计师为客户打造网络企业风格,提供周到的建站售前咨询和贴心的售后服务。对于网站设计、做网站中不同领域进行深入了解和探索,创新互联在网站建设中充分了解客户行业的需求,以灵动的思维在网页中充分展现,通过对客户行业精准市场调研,为客户提供的解决方案。
用递归的方法求1+2+3+4+…+(n-1)+n的值。
输入格式
一个整数n。(1<=n<=10000).
输出格式
一个整数,数列的和。
输入输出样例
输入
10
输出
55
题目出处
题目要求:用递归的方法求1+2+3+4+…+(n-1)+n的值。
#includeusing namespace std;
int f(int a){if(a==1)return 1;//边界
return (a+f(a-1));//递归关系式
}
int main(){int n;
cin>>n;
cout<
T2-T89307 Hermite多项式题目描述
用递归的方法求Hermite多项式的值
对给定的实数x和正整数n,求多项式值。
中间的Hermite图片
输入格式
两个数x,n。用空格隔开。(-1输出格式
一个数,函数值。(保留两位小数)
输入输出样例
输入
-0.10 1
输出
-0.20
题目出处
递归关系式已经给出来了,照着写呗。
#includeusing namespace std;
double n,x;//注意数据类型
double f(double n,double x){if(n==0)return 1;
if(n==1)return 2*x;
return 2*x*f(n-1,x)-2*(n-1)*f(n-2,x);//照着图片写呗
}
int main(){cin>>x>>n;
cout<
T3-T89310 递归函数求值1题目描述
已知图片
用递归方法求解。
输入格式
一行有两个整数x和n,用空格隔开。(1输出格式
一个实数,即函数值。(保留两位小数)
输入输出样例
输入
24499 8564
输出
2.86
题目出处
这一题比上一题略麻烦一点儿,要自己分析。
递归关系:f(x,n)=[n+f(n-1)]/x
边界:n=1时 return (1+x)/x
(或:当n=0时return x)
#includeusing namespace std;
int n,x;
double f(double x,double n){if(n==1)return x/(1+x);
return x/(n+f(x,n-1));
}
int main(){cin>>x>>n;
cout<
T4-T89314 递归函数求值2题目描述
已知
图片
根据x,n的值计算函数值。
输入格式
用空格隔开的两个数,实数x(0输出格式
函数值。保留两位小数。
输入输出样例
输入
4.2 10
输出
3.68
题目出处
递归关系:f(x,n)=sqrt(n+f(x,n-1))
边界:当n=1时return sqrt(1+x)
(或:当n=0时return x)
#includeusing namespace std;
float n,x;
double f(double x,double n){if(n==1)return sqrt(1+x);
return sqrt(n+f(x,n-1));
}
int main(){cin>>x>>n;
cout<
T5-T89316 汉诺塔问题题目描述
如图,设有n个大小不等的中空圆盘,按照从小到大的顺序迭套在立柱A上,另有两根立柱B和C。现要求把全部圆盘从A柱(源柱)移到C柱(目标柱),移动过程中可借助B柱(中间柱)。移动时有如下的要求:
1、一次只许移动一个盘。
2、任何时候任何柱子上不允许把大盘放在小盘上边。
3、可使用任意一根立柱暂存圆盘。
问:如何用最少步数实现n个盘子的移动,请打印出方案。
输入格式
一个整数n(3<=n<=16)
输出格式
输出移动最少的方案,每行表示一次移动,如A->B表示将A柱上最上面的圆盘移动到B柱上。
最后一行输出最少的步数。
图片
输入输出样例
输入
3
输出
A->C
A->B
C->B
A->C
B->A
B->C
A->C
7
题目出处
其实,可以将移动n个圆盘到目标柱理解为将(n-1)个圆盘移动到中间柱+移动第n个到目标柱+将(n-1)个圆盘移动到目标柱
也就是(递归关系式)
hanot(n-1,a,c,b);//(n-1)个圆盘移动到中间柱
cout<"<
边界
if(n==1)将这根柱子移动到目标柱
由于题目要步数,就设成了有返回值的(也可以定义全局变量替代)
#includeusing namespace std;
int n;
int hanot(int n,char a,char b,char c){//a目标柱,b中间柱,c目标柱
if(n==1){cout<"<"<cin>>n;
cout<
T6-T90615 字符串逆序题目描述
输入一串以‘!’结束的字符,按逆序输出。(请用递归完成)
输入格式
一行字符串(以!结束)(字符串长度不超过100)
输出格式
逆序输出。
输入输出样例
输入
abc!
输出
!cba
题目出处
这是我一开始的程序:
#includeusing namespace std;
string s;
string f(string s){int pos=s.size();
if(pos==1)return s;
char er=s[pos-1];
string st;
for(int i=0;icin>>s;
cout<
现在发现太繁琐:
#includeusing namespace std;
string s;
int pos;//全局变量,以便用于递归(当然,可以通过传参代替)
void f(int n){if(ncin>>s;
pos=s.size();
f(0);
cout<
呸呸,更正!!!
测试数据太弱了,竟然没测出BUG!!!
(将
cin>>s;
改为
getline(cin,s);
)
当然,还可以这样做:
#includeusing namespace std;
int pos;
void f(){char fox;
cin>>fox;
if(fox=='!'){cout<<"!";
return;
}//边界
f();
cout<f();
cout<
但注意!!!这个的BUG也是不能输入空格。将
cin>>fox;
改为
fox=getchar();
即可。
T7-T90627 费波那契数列1,1,2,3,5,8,13,…
这是著名的斐波那契(Leonardo Pisano ,Fibonacci, Leonardo Bigollo,1175-1250)发现的数列。其中,每两项都等于前二项之和(第1,2项是1)。
题目描述
1,1,2,3,5,8,13,21,34,55……从第三项起,每一项都是紧挨着的前两项的和。
以上就是斐波那契数列。
输入第几项,输出第几项的值。(请用递归完成)
输入格式
一个正整数n,<=30
输出格式
第n项的值
输入输出样例
输入
4
输出
3
题目出处
递归关系:f(n)=f(n-1)+f(n-2)
边界:当n==1或2时return 1
代码
#includeusing namespace std;
long long n,dp[110];//dp为记忆化数组,以空间换时间(当然本题数据较小,可以不用记忆化,并且可以不开long long)
long long f(long long n){if(n<=2){return 1;
}//边界
if(dp[n])return dp[n];
dp[n]=f(n-1)+f(n-2);
return dp[n];
}
int main(){cin>>n;
cout<
当然,还得展示一下我个人的奇葩代码,思路奇怪。(简直不能说是递归)像函数实现for循环
#includeusing namespace std;
int n,s=2;
int f(int a,int b){++s;
int c=a+b;
if(s==n)return c;
return f(b,c);
}
int main(){cin>>n;
if(n==1||n==2)cout<<1<
当然,再展示一下for循环代码
#includeusing namespace std;
long long n,dp[110];
int main(){cin>>n;
dp[1]=dp[2]=1;
for(int i=3;i<=n;++i)dp[i]=dp[i-1]+dp[i-2];
cout<
T8-T90628 F91题目描述
麦卡锡是一个有名的计算机科学专家,在他的著作中,他定义了一个被称为"F91"的递归函数,这个函数是这样获得的:输入一个正整数N,按如下定义返回一个正整数:
If N ≤ 100, then f91(N) = f91(f91(N+11));
If N ≥ 101, then f91(N) = N-10
编写程序计算出麦卡锡的F91函数
输入格式
输入数据包含一系列的正整数,每个正整数大不超过1,000,000,每个正整数占一行,当遇到数字0时表示输入结束。注意数字0不是测试数据,仅代表结束标志。
输出格式
输出数据每行应包含一个测试结果,具体格式见输出样例,等号两侧各有一个空格。
输入输出样例
输入
91
622
1997
0
输出
f91(91) = 91
f91(622) = 612
f91(1997) = 1987
说明/提示
输入数据保证你用直接递归不会超时。
题目出处
既然题目给出了递归关系式,并保证“直接递归不会超时”,那就写呗。
#includeusing namespace std;
int s=1;
int f(int s){if(s<=100)return f(f(s+11));//递归关系
return s-10;
}
int main(){while(s!=0){cin>>s;
if(s!=0){ cout<<"f91("<
T9-T90630 大公约数与最小公倍数题目描述
输入两个数,求他们的大公约数和最小公倍数。(请用递归完成)
输入格式
输入一行,两个正整数。
输出格式
输出一行,两个正整数(这两个正整数的大公约数和最小公倍数),用一个空格隔开。
输入输出样例
输入
18 20
输出
2 180
说明/提示
所有数据保证小于2^31-1
题目出处
既然是大公约数,肯定用“辗转相除法”。不了解的同学推荐看这篇C++辗转相除法详解,而大公倍数就是(设大公约数为x)(a/x)*(b/x)x=ab/x。可以参考这篇大公约数和最小公倍数的关系。
这题要递归实现(平常用的是迭代实现)
递归关系:f(a,b)=f(b,a%b)
边界:b==0时return a
附上我一开始的代码:
#includeusing namespace std;
int f(int a,int b){int c=b;
b=a%b;
a=c;
if(b==0)return a;
return f(a,b);
}
int main(){int n,a;
cin>>n>>a;
cout<
发现一种简洁优美的写法:(不会"? : "的同学可以看这篇C++中“?”的意思)
#includeusing namespace std;
long long a,b;
long long f(long long a,long long b){return b?f(b,a%b):a;
}
int main(){cin>>a>>b;
cout<
T10-T90632 十进制转八进制题目描述
把任一给定的十进制正整数(<=32000)转换成八进制数后输出。(请用递归完成)
输入格式
一个十进制数。
输出格式
转换后的八进制数
输入输出样例
输入
100
输出
144
题目出处
额……先来演示一下通常做法:
#includeusing namespace std;
long long a,b,i=1;
int main(){cin>>a;
while(a>0){b+=a%8*i;
a/=8;
i*=10;//算位权
}
cout<
简洁吧。。。下一步演示递归:
#includeusing namespace std;
int f(int n){if(n<8)return n;//也可以将边界改为0
return n%8+f(n/8)*10;
}
int main(){int n;
cin>>n;
cout<
还可以这么做
#includeusing namespace std;
void f(int n){if(n/8)f(n/8);
cout<int n;
cin>>n;
f(n);
return 0;
}
T11-T90633 走台阶题目描述
楼梯有n阶台阶,上楼可以一步上一阶,也可以一步上二阶。用递归的方法编一程序计算共有多少种不同的走法。(试用递归完成,会出现什么问题,如何解决)
输入格式
一个正整数n(n不超过90)
输出格式
一个整数,表示走法方案数。
输入输出样例
输入
4
输出
5
题目出处
我第一秒想到的是暴力……(造化低了)33分
#includeusing namespace std;
int n,cnt;
void f(int s){if(s==n){++cnt;
return;
}
if(s>n)return;
for(int i=1;i<=2;++i)
f(s+i);
return;
}
int main(){cin>>n;
f(0);
cout<
仔细对比数据,竟发现答案是斐波那契数列!!!
自制奇葩递归
#includeusing namespace std;
long long n,ans,vh[100];
void f(int s){if(s<3){if(s==2)cout<<3<cout<vh[0]=1;//这一行加上只是为了对比发现斐波那契,可删除
vh[1]=1;
vh[2]=2;
cin>>n;
f(3);
return 0;
}
标程:
#includeusing namespace std;
long long dp[110];//记忆化
long long f(long long n){if(dp[n])return dp[n];
if(n<=2)return n;//注意这个地方与标准斐波那契不同(因为这一题第n个答案是第(n+1)个斐波那契数,忘记的同学可以向上翻翻T7,这里原是return 1)
else dp[n]=f(n-1)+f(n-2);
return dp[n];
}
int main(){int n;
cin>>n;
cout<
刨根问底的同学可以继续看:
QUESTION:为什么答案是斐波那契数列?
ANSWER:上面我们用的是归纳的方法。下面主要介绍原因:
第1,2个台阶分别有1,2种走法(1)(1+1或2)
而从第3个开始,每一个数目(假设是第n个(n>2))都可以理解为第(n-1)的走法再走1级台阶或第(n-2)的走法再走2级台阶,自然就有第(n-1),第(n-2)的走法总数和数量的方法。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
当前文章:洛谷【C++编程基础】递归函数初步专题解题报告-创新互联
文章源于:http://cdiso.cn/article/igpic.html