当青训营遇上码上掘金
这次蓝桥杯阴差阳错之下报成了python组,所以这次的代码也选择了python解决了,正好这个问题是数据结构相关的,python的deque。就是需要的双向队列。
问题介绍
寻友之旅
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
**请帮助小青通知小码,小青最快到达时间是多久?**
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
解题思路
使用广度优先搜索算法来解决,从小青所在的地点开始,依次搜索小青可以到达的所有节点,然后分别下一步。 并且将这些数据都放到队列,这样当找到小码的时候,就可以返回最短时间。 此方法虽然比较方便,并且在边权为1的图中,算法比迪杰斯特拉还强。 时间复杂度为:3^n
deque库介绍
本次代码主要是利用这个库的内容,collections模块是Python标准库,数据结构常用的模块;collections包含了我们本次用到的deque,也就是双向队列。
双向队列(deque)是栈和队列的一种广义实现是类似于list的容器,可以快速的在队列头部和尾部添加、删除元素。 常用的有:
append() 从右端添加元素
appendleft() 从左端添加元素
extend() 从右端逐个添加可迭代对象
extendleft() 从左端逐个添加可迭代对象
pop() 移除列表中的一个元素(默认最右端的一个元素)
popleft() 移除列表中的一个元素(默认最左端的一个元素)
count() 统计队列中的元素个数
除此之外,还有插入反转等操作,因暂时用不到就先不介绍了,需要的时候再百度。
###代码解释
首先是几个定义,进行初始的设置steps = {} parent = {} queue = deque([n]) steps[n] = 0 parent[n] = None
然后设置循环,这里直接while 1,一直循环到底
在之后就是详细循环的步骤了 设置好结束条件,当走到小码所在位置时循环结束,也就是输出当前花费时间
if new == k:
return steps[k]
然后就是走路的路途计算步骤了,则是不停的进行队列的操作。也就是整个循环步骤里面的其他内容
最后附上完整代码
from collections import deque#支持双向队列
#利用数据结构里面的队列里的广度优先搜索
def queuesearch(n, k):
#deque是栈和队列的一种广义实现,是python里面的一个比较常用的库
steps = {}
parent = {}
queue = deque([n])
steps[n] = 0#shezhhi设置初始为0步
parent[n] = None#设置父节点
while 1:
new = queue.popleft()
# 二人汇合后返回步数
if new == k:
return steps[k]
# 将当前节点的左右节点加入队列
if new - 1 >= 0:
if new - 1 not in steps:
queue.append(new - 1)#右端添加元素
steps[new - 1] = steps[new] + 1
parent[new - 1] = new
if new + 1 <= 100000:
if new + 1 not in steps:
queue.append(new + 1)
steps[new + 1] = steps[new] + 1
parent[new + 1] = new
# 将当前节点的公交节点加入队列
if new * 2 <= 100000:
if new * 2 not in steps:
queue.append(new * 2)
steps[new * 2] = steps[new] + 1
parent[new * 2] = new
return -1
n=int(input("输入小青的位置:"))
k=int(input("输入小码的位置:"))
time = queuesearch(n,k)
print("最短时间:",time,"分钟")
参考文章: