递归系列---1.青蛙跳台阶 (10分)

递归系列—1.青蛙跳台阶 (10分)

在PTA上刷题,遇到这个问题,高三的时候听数学老师讲过,当时不知道什么是递归,现在明白了,觉得有点意思。

题意
一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法。

输入格式:
首先输入数字n,代表接下来有n组输入,50>=n>=0,然后每行一个数字,代表台阶数,数字为小于60的整数

输出格式:
对每一组输入,输出青蛙的跳法。

输入样例:
3
1
2
3

输出样例:
1
2
3

我对于递归的理解是,大的问题,可以转换成相同的,但是规模减少的相同的子问题,并且子问题减少的最小还要有解(递归有基准情况)。
常见用递归解决的问题有:前n项和,阶乘(循环也可以),还有著名的汉诺塔问题。一些常见的算法也有递归的思想在里面,比如快排等等,后续会介绍。
回到这个问题,这个问题想考的是递归,但是我递归最后一个测试点超时了,后来看了看数据,阶梯数小于等于60,单个测试了n=50时就不能输出结果,爆栈了。看了网上,应该是可以优化的,在递归之前,判断一下,这个数有没有算过,算过就直接输出,中断递归。
下面介绍一下循环的算的方法,不超时。

方法一:

#include<stdio.h>
long long step(int n)
{
	if (n <= 2)
		return n;
	long long a = 1, b = 2, c;
	int i = 2;
	for(i=2;i<n;i++)//后一项等于前两项之和
	{
		c = a + b;
		a = b;
		b = c;
	}
	return c;
}
int main()
{
	int x,T;
	scanf("%d",&T);
	while(T--)
    {
        scanf("%d",&x);
	    printf("%lld\n", step(x));
    }
	return 0;
}
 

讲两个坑点,这个step函数要设置成long long 型,50时候int 就超了,而且中间变量,a,b;也要设置成 long long。

在这里插入图片描述

方法二:
递归的方法
递归的核心就是,return。代表着子问题和原本问题的关系。在这题中,n个台阶的跳法等于n-1个台阶的跳法,加上n-2的台阶的跳法,相当于,我从n的台阶退到n-2阶的台阶,可以退一步得到n-1阶,也可以是退两步到n-2阶。

递归的结束情况,这题是,当只有一个台阶时只有一种走法,两个台阶的时候两种走法。

#include <stdio.h>
long long f[500]={0};
long long count(int n)
{
    if(f[n]==0)
    {
        if(n==1||n==2)
            return n;
        else
            return count(n-1)+count(n-2);
    }
    else
        return f[n];
}
int main()
{
    int T,n;
    long long temp;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        if(f[n]==0)
        {
            temp=count(n);
            f[n]=count(n);//记录算过的数
        }
        else
            temp=f[n];
        printf("%lld\n",temp);
    }
    return 0;
}

这是改进后的递归,加了判断,但是还是没过最后一个点,但是在调试的时候,你从40-50这十一个点是可以算出来50的,而且速度很快,说明,加的判断生效了。可以返回之前算过的数。
在这里插入图片描述
其实,这个题还是个斐波那契数列 (1)1 2 3 5 8 13 21…后一项是前两项之和,和兔子繁殖的题目也是一样的,感兴趣的可以去搜搜。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值