递归

递归就是一个反复调用的过程,直到找到一个可以已知的引用对象即可。

解答递推的题目,可能唯一的方法就是找到题目中的规律,利用规律来写出代码,一般代码比较简洁,但是推算规律的过程需要些时间,同样也得花时间来钻研和训练推算规律的能力。

在做山东理工大学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;
}


3479青蛙过河——规律是石柱和荷叶的数量是一个有规律的:(s-1,y)*2  //s为石柱,y是荷叶。

#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);
		}
	}
	
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值