九连环的递归解法

最近在重温数据结构和算法分析。刚好手头有个九连环,就想着用递归写写个九连环的解法。九连环解法的基本原则:

  • 第一个环在任何时候都是可以自由上下的
  • 如果希望第 n 个环能自由上下,那么
    – 第 n-1 个环必须在杆上
    – 前面第 n-2 个环全部不在杆上

这三个简单规则就构成了递归解法的基础。

%matplotlib qt
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
# 模拟九连环,1表示在杆上,0表示不在
ring = [0,1,1,1,1,1,1,1,1,1]
UP = 1
DOWN = 0
steps = 0 
fig = plt.figure(figsize=(12,3))

def visual(steps,index,action):
    if action == UP:
        title = 'setp-%s: %s ring UP'%(steps,index)
    else:
        title = 'setp-%s: %s ring DOWN'%(steps,index)
        
    plt.cla()
    ax = fig.add_subplot(111)
    plt.axis('off')
    plt.plot([1,35],[7,7],'k-',linewidth=2)
    for i in range(1,10):
        y = ring[i]*3+4
        color = 'red' if ring[i] else 'blue'
        cir = Circle(xy = (3.5*i, y), radius=1, alpha=0.5,facecolor= color)
        ax.add_patch(cir)
    plt.title(title)
    plt.axis([0,40,0,10])
    plt.pause(0.5)

def ring_updown(index,action):
    # 如果是第一个环,那么可以自由拆卸
    global steps
    if index == 1:
        steps += 1
        ring[index] = action
        visual(steps,index,action)
        return None
    
    # 如果第 n-1 个环不在杆上,需要先装上
    if ring[index-1] == 0: #  n-1 not on the ring
        ring_updown(index-1,UP)
    
    # n-2 个环需要全部不在杆上,如果有环在杆上,需要先卸下来
    for i in range(index-2,0,-1):
        if ring[i] == 1: # n-2,n-3,... no the ring
            ring_updown(i,DOWN)
    
    steps += 1
    ring[index] = action
    visual(steps,index,action)
    return None

for i in range(9,0,-1):
    ring_updown(i,DOWN)

上面的代码,除去图示的部分,只有10行有效代码。
在这里插入图片描述
一共执行了341步骤。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值