关于每周两题---1

斐波那契数

题目:
菲波那契数列是指这样的数列:数列的第一个和第二个数都为1,接下来每个数都等于前面2个数之和。给出一个正整数k,要求菲波那契数列中第k个数是多少。
输入一行,包含一个正整数k。(1 ≤ k ≤ 46)
输出一行,包含一个正整数,表示菲波那契数列中第k个数的大小。

思路:
每个数为前两个数之和,刚开始想的一直都是利用循环,利用数列求解,直接保存第一个第二个数在数列里,然后利用循坏,当前i的值为列表前两位的和,结果就是想法错误,过不去测试。 然后去搜索,查出不同的答案(有很多种,这里只描述简单的三种方法)。

  1. 循环(一直想到的但又没实现的,测评的效率还可以)
k=int(input())
f1,f2=1,1
current=0
if k<=2:
    print(f1)
else:
    for i in range(3,k+1):
        current=f1+f2
        f1=f2
        f2=current
    print(current)

有一个交换数的作用,假设i=3,current=f1+f2=2,交换数值后f1=1,f2=2(通俗来讲就是把f1,f2当作指针,刚开始指向1,1,循环一次后两个指针分别后移一位,f1就会指到f2,f2就会指到current,然后不断循环)

  1. 递归函数(测评效率最低,时间太长)
    回忆一下,递归函数,调用函数自身的方式称为递归,例子之一是求阶乘n!
  • 递归函数通常包含两个部分:基本情况 & 递归情况
    • 基本情况是指当满足某个条件时,函数直接返回结果,而不再调用自身。
    • 递归情况是指函数在未满足基本情况时,将问题分解为更小的子问题,并通过调用自身来解决这些子问题。

递归函数的设计和使用需要小心,因为如果没有正确定义基本情况或递归情况,函数可能会无限递归下去,导致堆栈溢出。另外,递归函数的性能比较低,因为每次函数调用都需要保存当前的执行状态

  • 什么情况下需要使用递归函数?
    递归函数在许多算法和数据结构问题中非常有用,例如树的遍历、排列组合、动态规划等。通过合理地设计递归函数,可以简化问题的解决过程,并使代码更加清晰和易于理解。
    • 树形结构的遍历:递归函数在遍历树形结构(如二叉树、多叉树)时非常实用。通过递归调用自身,可以依次访问树的每个节点,实现先序、中序或后序遍历。
    • 排列和组合问题:递归函数在排列和组合问题中也非常有用。通过递归调用自身,在每一步选择不同的元素来生成不同的排列或组合。
    • 动态规划问题:动态规划是通过将大问题分解为子问题,并存储子问题的解来解决问题的方法。递归函数在动态规划问题中常常用于计算子问题的解,从而得到整个问题的解。
def fib(k):
    if k<=2:
        return 1
    else:
        return fib(k-1)+fib(k-2)
        
k=int(input())
print(fib(k))

效率最低,会出现大量的重复计算,时间复杂度O(1.618^n),而且最深度1000

  1. 尾递归函数(第一回听说(真的小白))
def fibonacci(n, a=1, b=1):
    if n <= 2:
        return b
    else:
        return fibonacci(n-1, b, a+b)
k=int(input())
print(fibonacci(k))

这里使用了默认参数的方法,其中a和b分别代表Fibonacci数列中的第n-1项和第n项。调用fibonacci(n)即可获得第n项的值。(和第一种方法本质上一样,就是交换值所实现)

尾递归是指递归函数在调用自身时直接传递其状态值。在这些语言中尾部递归不会占用调用堆栈空间。

python-递归和递推
可以见这个博主的介绍了解 ,链接:https://blog.csdn.net/weixin_43955170/article/details/115714881

校外的树

题目:
某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。
由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。

  • 输入描述:
    第一行有两个整数L和 M,L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。对于20%的数据,区域之间没有重合的部分;对于其它的数据,区域之间有重合的情况。
  • 输出描述:
    包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。

想法:刚开始知道怎么减,就是不知道重合部分怎么去计算 ,搜索之后发现,是有一个坐标轴(虽然题目说了但没仔细看),起始从0,一共有L+1棵树,创建L+1大小的列表,使其数值全为1,接着遍历M,接收区域值,并使这些区域在列表上对应下标的数值变为0(就是移走的意思),最后求和列表,就知道有多少颗树未被移走。

L,M = map(int,input().split())
li=[]
for i in range(0,L+1):
    li.append(1)
for i in range (M):
    a,b=map(int,input().split())
    for k in range(a-1,b):#第a颗树在列表中下标为a-1,第b颗树在列表中下标为b-1
        li[k]=0#直接使其变为0
print(sum(li))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值