好友在微信上转了一个题,题目如下:
“把你的手机拨号页想象成一个棋盘。棋子走只能走“L”形状,横着两步,竖着一步;或者竖着两步,横着一步。
现在,假设你拨号只能像棋子一样走“L”形状。每走完一个“L”形拨一次号,起始位置也算拨号一次。问题:从某点开始,在N步内,你可以拨到多少不同的数字?”
比如:从1开始走3步,那么就相当于是 1,6,7。
自己有段时间没用类封装了,所以这次练习我用上来类封装,下面是代码:
class Key_jump():
def __init__(self, x, num):
# 初始化起点和跳跃次数
self.x = x
self.num = num
# 下面用枚举的方式列出了当前位置可以跳跃的点
self.jump_next = {
1: (6, 8),
2: (7, 9),
3: (4, 8),
4: (3, 9, 0),
5: '',
6: (1, 7, 0),
7: (2, 6),
8: (1, 3),
9: (2, 4),
0: (4, 6)
}
# 用来保存结果和失败结果即跳到了死胡同的路线
self.result_list = []
self.break_list = []
print('从%d开始跳%d次' % (x, num))
# 定义一个方法第一次跳跃即以初始值起跳
def first_jump(self):
# 记录起点位置
path = str(self.x)
# 判断结束条件:次数为0以及没有下一个可跳的点
self.num -= 1
if not self.jump_next[self.x] or self.num == 0:
# 将结果保存
self.result_list.append(path)
return
for next_x in self.jump_next[self.x]:
# 对下一个点遍历带入后面的跳跃方法(递归)
self.jump(next_x, self.num, path)
def jump(self, x, num, path):
# 首先记录跳跃路径
path += '-' + str(x)
# 次数减一
new_num = num - 1
# 判断结束条件
if not self.jump_next[x] or new_num == 0:
# 保存路径
return self.result_list.append(path)
else:
for next_x in self.jump_next[x]:
# 对下一个跳跃点遍历
# 判断该点是否出现在路径中(因为不能重复)
if str(next_x) in path:
# 保存中断路径
break_path = path + '-' + str(next_x)
self.break_list.append(break_path)
continue
# 通过上面的判断后将该点带入跳跃方法递归
self.jump(next_x, new_num, path)
def show_res(self):
# 打印结果
for path in self.result_list:
print('成功路线:%s' % path)
for path in self.break_list:
print('中断路线:%s' % path)
def run(self):
# 组合方法,先跳跃,后打印结果
self.first_jump()
self.show_res()
if __name__ == '__main__':
a = Key_jump(3, 5)
a.run()
贴一张运行结果的图:
当然这个还没有做任何的优化,希望能有大神在评论里提出优化建议。