常见递归问题 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')
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,
#输出棋局方阵
for m in range(8):
#输出左侧的行标
print m,
for n in range(8):
if QueenList
==m:
print "Q",
else:
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')
相关文章推荐
- python实例-暂停一秒
- python2.0_s12_day11_SqlAlchemy使用介绍
- Python模块之Logging(五)——在配置文件中为Logger配置多个handler
- Python实战1_3:爬取租房信息
- Python 核心编程笔记_Chapter_3 Note_4 创建python文件(练习文件操作)
- Python filter map reduce lambda Method detail
- 进制转换
- python高级
- python基础
- python运算符重载
- sublime下的python及插件安装
- Python脚本实现值更新事件赋值过程记录日志监控
- Python脚本实现单据体背景色及字段前景色设置
- API例子:用Python驱动Firefox采集网页数据
- python代码的那些设计
- Python及科学计算库的安装
- Python_day8_面向对象(多态、成员修饰符、类中特殊方法、对象边缘知识)、异常处理之篇
- Python 核心编程笔记_Chapter_3 Note_3 内存管理_垃圾回收
- python set 学习笔记
- Python 核心编程笔记_Chapter_3 Note_3 内存管理_垃圾回收