题目如下:
请编写递推函数move(n, a, b, c),它接收参数n,表示3个柱子A、B、C中第1个柱子A的盘子数量,然后打印出把所有盘子从A借助B移动到C的方法
汉诺塔移动规则如下:
1. 在小圆盘上不能放大圆盘
2. 在三根柱子之间一次只能移动一个圆盘
分析如下:
首先我们需要列举n的几种取值来找出规律, >表示移动
当n=1时,A>C;
当n=2时,A>B, A>C, B>C;
当n=3时,A>C, A>B, C>B, A>C, B>A, B>C, A>C
汉诺塔移动规律总结如下(最精华的部分):
1. 将底塔之上的所有塔移动到过渡柱子
2. 将底塔移动到目标柱子
3. 将过渡柱子上的其他塔移动到目标柱子
代码准备:
n=1时:第n次移动的步骤=A>C
n>1时:第n次移动的步骤=第n-1次移动的步骤+(A>C)+第n-1次移动的步骤
但是需要注意的是上述公式右侧第一个【第n-1次移动的步骤】的起始柱不变,但目标柱应该是过渡柱。
而上述公式右侧第二个【第n-1次移动的步骤】的目标柱不变,但起始应该是过渡柱。
所以我们只需要改变在函数内部调用move(n,a,b,c)函数时的特定的变量即可,具体当n>1时,n个盘子移动用到打印步骤方法应该如下:
move(n,a,b,c)=move(n-1,a,c,b)+print(a,'<',c)+move(n-1,b,a,c)
所以我们完成这道题目的任务就转变为分别写n=1和n>1时的代码即可,可以注意到上式中print(a,'<',c)可以替换为move(1,a,b,c),也就是n=1时的情况。
我们用if...else...来解决n=1和n>1的情况
move()函数代码如下:
def move(n,a,b,c):
if n == 1:
print(a,'>',c)
else:
move(n-1,a,c,b)
print(a,'>',c)
move(n-1,b,a,c)
总结:
汉诺塔的移动可看作在更改起始柱、过渡柱和目标柱情况下n=1的不断重复。