"""
汉诺塔问题:64个盘子,一天一次,需要多少天?
思考
究竟什么问题:找到规律,得出公式,得出64数量需要多少次移动。
元素:盘子/移动次数/规则,小的必须在大的之上。
属性:
1.按照步骤来
二个盘,先移动小的到奇数柱子,再移动大的到偶数柱子,再移动小的到偶数柱子。
三个盘子:两个盘子走3步,移动三号盘,复原两个盘子三步。
四个盘子: 三个盘子七步,移动四号盘,复原三个盘子七步
n个盘子, a(n)=2a(n_1) + 1
2.通项式的转化
方式一:
a(2) - a(1) = 2
a(3) - a(2) = 4
...8, 16, 32 也就是等比数列. 等比数列的求和公式 sn =
相加得出 a(n)- a(1) = sn
a(n) = 2^(n) - 1
方式二:
a(n)=2a(n_1) + 1
转化成xy轴图像y = 2x + 1,与y = x 的直线的交点 为a(-1,-1), 设a为原点 , 可消除截距的影响 = 原点(0,0)变为(-1, -1) >>>> x+1的y值为原y值
设 b(n) = a(n) + 1 , 带入 a(n) = 2a(n-1) + 1 , 得 b(n) = 2 b(n-1) >>> 等比数列:q=2 a(n)= a(1)q** (n-1)
, 该通项式: b(n) = 2 ** (n-1) >>>b(n) = b(1) * 2 (n-1)>>>代入 b(n) = a(n) +1 与b1 = a1 +1
得: a(n) = 2 **n -1
"""
'''
#方式一: 按照规律1步1计数
思考:代码实现需要什么元素
元素:获取盘子数量/代码块/计数器增加/输出计数器
目的:模拟汉诺塔的每一步操作 >>> 定义函数
1:(放1)
2:((放1),放2,(放1))
3:(放1,放2,放1.放3,放1,放2,放1)
4:((放1,放2,放1.放3,放1,放2,放1),放4,(放1,放2,放1.放3,放1,放2,放1))
规律:
分解成: 计算机 可识别, 可重复步骤
step1 = 1
step2 = step1 + 1 + step1
step3 = step2 + 1 + step2
step4 = step3 + 1 + step3
'''
def hannuo2():
step = 1
n = int(input("汉诺塔步数计算2\n输入金盘数量:"))
for i in range(n):
step = step + 1 + step
print(step)
"""
方式二:
规律:通项式 >>> 次数= 2**n - 1 , 内置计算步骤得出结果
优势: 通过算法,节省计算机资源,避免模拟步骤情况的栈溢出
yxf2026
适用场景: 重复步骤多的问题
"""
def hannuo():
n = int(input("汉诺塔步数计算器1\n输入金盘数量:"))
step = 2**n - 1
print(step)
hannuo2()
# 需求2 汉诺塔输出 具体的操作方式
'''
思考: 有系统性问题,思考元素与关联性, 找到属性
元素:
三个柱子: 属性-固定数量3
盘子: 属性-不具体数量,不具体大小,不具体编号
移动路径:柱子间来回移动
系统本质:
杠杆点--只考虑移动路径为输出结果.
代码实现:
一、明确递归函数的本质
1.确定要做什么(定义清晰)
2.找出最简单的情况(递归出口)
3.如何大问题变成小的同类问题
4.结果组合
二、明确需求:汉诺塔问题的移动路径规律
1.规律:
n=1时, a>>>c
n=2时,
a>>>b
a>>>c
b>>>c
数量为n时: 分两部分,N与N-1以上
步骤:
1.n-1整体移动到b柱 2.N移动到c柱 3.n-1移动到C柱
2.递归实现(a=A柱, b=B柱, c=C柱)
├──n-1一体 a到b
│ ├── n-2一体 a到b
│ │
│ ├── n-1单独 a到c
│ └── n-2 b到c
├── n单独 a到c
│
└── n-1 b到c
├── n-2 b到a
│
├── n-1单独 b到c
└── n-2 a到c
'''
def hn3(n,star, mid, end):
"""
汉诺塔步骤模拟器
:param n: 汉诺塔圆盘数量
:param star: 起始柱A
:param mid: 过程柱B
:param end: 结束柱C
:return: 输出每一步的移动路径
yxf2026
"""
if n == 1:
print('编号:',n,star ,'>>>',end) #02
else:
#打印程序是(star >>> end) = (A柱>>>C柱),需求是a的目标是移动到b, 交换B柱与C柱位置,传参后就会打印 A柱>>>B柱
hn3(n-1,star,end,mid) # 03
print('编号:',n,star, '>>>', end) # 04
#打印程序是(star >>> end) = (A柱>>>C柱),需求是b的目标是移动到C, 交换B柱与a柱位置,传参后就会打印 B柱>>>c柱
hn3(n-1,mid,star,end) #05
hn3(3,'A柱','B柱','C柱')
'''
3个盘子执行结果树状图
hn3(3, 'A柱', 'B柱', 'C柱')
│
├── 执行: hn3(2, 'A柱', 'C柱', 'B柱')
│ ├── 执行: hn3(1, 'A柱', 'B柱', 'C柱')
│ │ └── 输出: 1 A柱 >>> C柱
│ ├── 输出: 2 A柱 >>> B柱
│ └── 执行: hn3(1, 'C柱', 'A柱', 'B柱')
│ └── 输出: 1 C柱 >>> B柱
│
├── 输出: 3 A柱 >>> C柱
│
└── 执行: hn3(2, 'B柱', 'A柱', 'C柱')
├── 执行: hn3(1, 'B柱', 'C柱', 'A柱')
│ └── 输出: 1 B柱 >>> A柱
├── 输出: 2 B柱 >>> C柱
└── 执行: hn3(1, 'A柱', 'B柱', 'C柱')
└── 输出: 1 A柱 >>> C柱
'''