递归就是一个反复调用的过程,直到找到一个可以已知的引用对象即可。
解答递推的题目,可能唯一的方法就是找到题目中的规律,利用规律来写出代码,一般代码比较简洁,但是推算规律的过程需要些时间,同样也得花时间来钻研和训练推算规律的能力。
在做山东理工大学ACM中,具有有以下几道题目用到了递归,在此总结以下:
2176递归的函数——这道题可能有点坑,大多数人看到题目,不用想直接用递归做,就得出答案,可是提交之后就会方法运行时间超市,这就是递归的一个坏处,递归算法的效率是比非递归要低的。 一开始,我也用了递归提交数次错误后直接百度的,发现递归由于自身的限制,所以这道题递归会出现超时。所以就用了一个三维数组存输入的数,三个for循环根据条件来运算出a[i][j][k]满足题目要求的数据,在每次输入x,y,z直接根据条件输出该输出的数据就可以。
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int main(){
int a[21][21][21];
int x,y,z;
int i,j,k;
for(i=0;i<21;i++){
for(j=0;j<21;j++){
for(k=0;k<21;k++){
if(i<=0||j<=0||k<=0)
a[i][j][k]=1;
else if(i>20||j>20||k>20)
a[i][j][k]=a[20][20][20];
else if(i<j&&j<k)
a[i][j][k]=a[i][j][k-1]+a[i][j-1][k-1]-a[i][j-1][k];
else
a[i][j][k]=a[i-1][j][k]+a[i-1][j-1][k]+a[i-1][j][k-1]-a[i-1][j-1][k-1];
}
}
}
while(scanf("%d%d%d",&x,&y,&z)!=EOF){
if(x<=0||y<=0||z<=0)
printf("1\n");
else if(x>20||y>20||z>20)
printf("%d\n",a[20][20][20]);
else
printf("%d\n",a[x][y][z]);
}
return 0;
}
2064汉诺塔系列1——这道题读题都没读懂,也就无从下手,但从输入输出中发现其中的规律,输入与输出是一个关于3的n次方的规律。3^1=3,3^3=27,3^29=68630377364883。
#include<stdio.h>
#include<math.h>
int main(){
int n,m;
long long sum;
int i;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&m);
sum=pow(3,m);
printf("%lld\n",sum);
}
return 0;
}
#include<stdio.h>
int qingwa(int s,int y){
if(s==0)
return y+1;
else if(s!=0)
return (qingwa(s-1,y)*2);
}
int main(){
int s,y;
while(scanf("%d%d",&s,&y)!=EOF){
printf("%d\n",qingwa(s,y));
}
return 0;
}
3478数值的分解——
#include<stdio.h>
int main()
{
int mui;
int num, count;
while(scanf("%d",&num)!=EOF) //输入所需要分解的数字
{
mui = 1; //mui代表分解数值的乘值初始为1
count = 0;
while(num > 4) //【hint】只有把N分成尽可能多的3,它们的乘积才能最大(当只剩下4时不用再分,因为: 4 > 3*1)
{
num = num - 3;
printf("3 ");
count ++; //计入分解的次数
mui = mui * 3; //进行分解数值的乘积运算
}
if (num <= 4) count ++;
printf("%d \n",num);
printf("%d %d\n",count, mui * num);
}
return 0;
}
3470数学黑洞——
#include<iostream>
#include<algorithm>
using namespace std;
int a[5];
int res,num;
void f(int n)
{
int max1 = 0,min1=0;
for(int i = 0; i < 4; i++)
{
a[i] = n%10;
n/=10;
}
sort(a,a+4);
for(int i = 0; i < 4; i++)
min1 = a[i] + min1*10;
for(int i = 3; i>=0; i--)
max1 = a[i] + max1*10;
res = max1 - min1;
if(res==6174)
{
cout<<res<<" "<<endl;
num++;
cout<<num<<endl;
}
else
{
cout<<res<<" ";
num++;
f(res);
}
}
int main()
{
int n;
while(cin>>n)
{
res = 0;
num = 0;
f(n);
}
return 0;
}
1217蟠桃记——
#include<stdio.h>
int main(){
int m,i;
int d1,d2;
while(scanf("%d",&m)!=EOF,m){
d1=1;
for(i=1;i<m;i++){
d2=(d1+1)*2;
d1=d2;
}
printf("%d\n",d1);
}
return 0;
}
2066汉诺塔系列2——
#include<stdio.h>
#include<math.h>
int main(){
int t;
int n,m;
int i;
while(scanf("%d",&t)!=EOF){
long long sum=0;
while(t--){
scanf("%d%d",&n,&m);
sum=pow(2,n-m);
printf("%lld\n",sum);
}
}
return 0;
}
2872M二分查找——
#include<stdio.h>
int a[3123456];
int n;
int find(int low,int high,int key){ //二分查找
while(low<=high){
int mid=(high+low)/2;
if(a[mid]==key)
return mid;
else if(a[mid]>key)
high=mid-1;
else if(a[mid]<key)
low=mid+1;
}
return -1;
}
int main(){
while(scanf("%d",&n)!=EOF){
int i;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
int q;
scanf("%d",&q);
int key;
for(i=0;i<q;i++){
scanf("%d",&key);
int cnt=find(1,n,key);
printf("%d\n",cnt);
}
}
}