您的位置:首页 > 编程语言 > Python开发

常见递归问题 Python解法

2016-06-29 13:57 621 查看
1.  求1+2+3+……+n的值

def fun(n):
    if n==1:return 1
    return n+fun(n-1)
 
a=int(raw_input("输入一个数计算累加:"))
print fun(a)

2.  求1*2*3*……*n的值

def fun(n):
    if n==1:return 1
    return n*fun(n-1) 
 
a=int(raw_input("输入一个数计算累加\求阶乘:"))
print fun(a)
 

5. 小猴子第一天摘下若干桃子,当即吃掉一半,又多吃一个.第二天早上又将剩下的桃子吃一半,又多吃一个.以后每天早上吃前一天剩下的一半另一个.到第10天早上猴子想再吃时发现,只剩下一个桃子了.问第一天猴子共摘多少个桃子?

def peach(n):
    if n==1:return 1
    return (peach(n-1)+1)*2
 
print peach(10)
输出:1534

 

6. 有雌雄一对兔子,假定过两个月便可繁殖雌雄各一的一对小兔子。问过n个月后共有多少对兔子?

def rabbit(n):
    if n==1:
        return 1
    elif n==2:
        return 1
    else:
        return rabbit(n-1)+rabbit(n-2)
拉契(Fibonacci)数列

7.  一个人赶着鸭子去每个村庄卖,每经过一个村子卖去所赶鸭子的一半又一只。这样他经过了七个村子后还剩两只鸭子,问他出发时共赶多少只鸭子?经过每个村子卖出多少只鸭子?

def duck(n):
    if n==7:
        return 2
    else:
        tmp=(duck(n+1)+1)*2
        return tmp
#n1是过了第一个村剩余的鸭子数,init是最初的鸭子数,保存是为了下次使用不用再求一次值   

n1=duck(1)
init=(n1+1)*2
print "最开始有%d只鸭子"%init
 
#上一村剩余的鸭子数
last=init
for i in range(1,8):
        #这一村剩余的鸭子数
        this=duck(i)
        print "在第%d个村子,卖出%d只鸭子"%(i,last-this)
        last=this
输出:
最开始有510只鸭子

在第1个村子,卖出256只鸭子

在第2个村子,卖出128只鸭子

在第3个村子,卖出64只鸭子

在第4个村子,卖出32只鸭子

在第5个村子,卖出16只鸭子

在第6个村子,卖出8只鸭子

在第7个村子,卖出4只鸭子

8.  著名的菲波拉契(Fibonacci)数列,其第一项为0,第二项为1,从第三项开始,其每一项都是前两项的和。编程求出该数列前N项数据。

def fib(n):
    if n==1 or n==2:
        return 1
    else:
        return fib(n-1)+fib(n-2)
 
for i in range(1,11):
    print fib(i)
9.  求两个数的最大公约数。

def gcd(m,n):
    temp=m%n
    if temp==0:return n
    else:
        m=n
        n=temp
        return gcd(m,n)
 
a=input("输入两个数,求最大公约数,第一个数:")
b=input("第二个数:")
print "最大公约数:%d" %gcd(a,b)
 

10.  求两个数的最小公倍数。

def lcm(s,m,n):
    if s%n==0:return s
    else:
        return lcm(s+m,m,n)
   
a=input("输入两个数,求最小公倍数,第一个数:")
b=input("第二个数:")
print "最小公倍数:%d" %lcm(a,a,b)
 

12.  角谷定理。输入一个自然数,若为偶数,则把它除以2,若为奇数,则把它乘以3加1。经过如此有限次运算后,总可以得到自然数值1。求经过多少次可得到自然数1。

如:输入22,

输出 22  11  34  17  52 26  13  40  20  10  5  16  8  4 2  1

     STEP=16

 
times=0
def fun(num):
    global times
    if num==1:
        print num,
        print "Step",times
        return
    else:
        print num,
        if num%2==0:
            times+=1
            num/=2
        else:
            times+=1
            num=num*3+1
           
    fun(num)
 
 
fun(22)
 

13.  将十进制转换为二进制。

 
_a=[]
def to2(n):
    global _a
    if n==1:
        print n%2,
        _a.append(n%2)
        return
    else:
        print n%2,
        _a.append(n%2)
        to2(n/2)
num=int(raw_input("输入一个十进制数:"))
to2(num)
_a.reverse()
print _a
   
15.  梯有N阶,上楼可以一步上一阶,也可以一次上二阶。编一个程序,计算共有多少种不同的走法。
def climbStep(n):
    if n==1:
        return 1
    elif n==2:
        return 2
    else:
        return climbStep(n-1)+climbStep(n-2)
 
print climbStep(10)
输出89

16.     某人写了n封信和n个信封,如果所有的信都装错了信封。求所有的信都装错信封共有多少种不同情况?

 

分析:

1、当N=1和2时,易得解~,假设F(N-1)和F(N-2)已经得到,重点分析下面的情况:2、当有N封信的时候,前面N-1封信可以有N-1或者N-2封错装

3、前者,对于每种错装,可从N-1封信中任意取一封和第N封错装,故=F(N-1)*(N-1)

4、后者简单,只能是没装错的那封和第N封交换信封,没装错的那封可以是前面N-1封中的任意一个,

故= F(N-2) * (N-1)

 

得到如下递推公式:

基本形式:d[1]=0;   d[2]=1

递归式:d
= (n-1)*( d[n-1] + d[n-2])
def mixLetter(n):
    if n==1:
        return 0
    elif n==2:
        return 1
    else:
        return(n-1)*(mixLetter(n-1)+mixLetter(n-2))
 
print mixLetter(5)

18.八皇后
  在8*8国际象棋棋盘上,要求在每一行放置一个皇后,且能做到在竖方向,斜方向都没有冲突。国际象棋的棋盘如下图所示:

分析
  基本思路如上面分析一致,我们采用逐步试探的方式,先从一个方向往前走,能进则进,不能进则退,尝试另外的路径。首先我们来分析一下国际象棋的规则,这些规则能够限制我们的前进,也就是我们前进途中的障碍物。一个皇后q(x,y)能被满足以下条件的皇后q(row,col)吃掉
1)x=row(在纵向不能有两个皇后)
2)  y=col(横向)
3)col + row = y+x;(斜向正方向)
4)  col - row = y-x;(斜向反方向)
 
def isSafe(row,col,QueenList):
    #'判断棋局中的一个格子是否可以安放皇后,满足3个条件,和其他皇后不同行、不同列、各自坐标的和与差不能相同(斜着不在一条线上)#'
    for i in range(col):
        if(QueenList[i]==row orrow+col==QueenList[i]+i or row-col==QueenList[i]-i):
            return False
    return True
 
def placeQueen(col,QueenList):
    row=0
    goodPos=False
    #终止条件,检查到完了所有8列,所有的8列都能正常安放皇后
    if col==8:
        goodPos=True
    else:
        while row<8 and not goodPos:
            #在一个给定的列中,检查所有行,看是否可以放皇后,如果可以,则验证下一列是否有位置可以安放皇后,一直检查到第8列,所有列都能,才返回goodPos为true
            if isSafe(row,col,QueenList):
                QueenList[col]=row
               goodPos=placeQueen(col+1,QueenList)
                #放在该行,由于后面的列无处放皇后,所以尝试下一行
               if not goodPos:
                    row+=1
            else:
                #因为该行不能放皇后,直接到下一行
                row+=1
    return goodPos
 
#这里为QueenList赋初值,是权宜之计,需要改进
QueenList=[10,10,10,10,10,10,10,10]
for i in range(8):
    QueenList[0]=i
   res=placeQueen(1,QueenList)
    print "第一个皇后放在",i
    if res:
        #输入出棋局上面的列标
        print " ",
        for a in range(8):
            print a,
        print
        #输出棋局方阵
        for m in range(8):
            #输出左侧的行标
            print m,
            for n in range(8):
                if QueenList
==m:
                    print "Q",
                else:
                    print "*",
            print
 
    else:
        print "没有好的排列"
    print "-----------------"

19、汉诺依塔问题
def hanoi(n,origin,assist,destination):
    if n==1:
        printorigin,"-->",destination
    else:
        hanoi(n-1,origin,destination,assist)
        printorigin,"-->",destination
        hanoi(n-1,assist,origin,destination)
 
hanoi(5,'A','B','C')
 
 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: