常见递归问题 Python解法

来源:互联网 发布:小米网络机顶盒多少钱 编辑:程序博客网 时间:2024/06/08 08:34

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]= (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[n]==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')

 

 

 

0 0
原创粉丝点击