题目
寻友之旅
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
##代码
from collections import deque
def shortest_time(N, K):
"""
这个程序解决以下问题:
寻友之旅
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
作者:青训营官方账号
链接:https://juejin.cn/post/7187753682421678137
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
"""
# 创建一个双端队列,存储初始状态
q = deque([(N, 0)])
# 创建一个集合,存储已经访问过的节点
visited = set()
# 当队列不为空时
while q:
# 从队列头取出状态
node, time = q.popleft()
# 如果当前节点为目标节点,则返回时间
if node == K:
return time
# 如果当前节点没有访问过
if node not in visited:
# 将当前节点加入已访问节点集合
visited.add(node)
# 将当前节点步行到下一个节点的状态加入队列
q.append((node - 1, time + 1))
# 将当前节点步行到下一个节点的状态加入队列
q.append((node + 1, time + 1))
# 将当前节点乘坐公交到下一个节点的状态加入队列
q.append((node * 2, time + 1))
# 如果队列为空,则返回-1
return -1
if __name__ == '__main__':
N, K = map(int, "5 17".split())
print(shortest_time(N, K))
总结
这道题属于图论和贪心问题。主要思路是利用广搜算法来搜索从初始节点到目标节点的最短路径。BFS(广度优先搜索)算法,是一种图搜索算法,用于在图中查找最短路径。BFS算法的基本思想是从起始节点开始,沿着图的宽度遍历图中的节点,直到找到目标节点为止。BFS算法可以以最短时间找到最短路径,使用双端队列(deque)存储状态,并且使用一个集合(set)记录访问过的节点,以避免重复访问。
BFS算法可以用于解决很多其他的图搜索问题,例如最少步数问题、最少转换问题、最少时间问题、最少代价问题、最大流量问题、最大匹配问题、最大权重匹配问题、最大连通子图问题、最小生成树问题、最小割集问题和其他图搜索问题。
关于这类题型,一般来说都是求最短路径,可以使用广搜、DFS、BFS等图论算法。这里介绍广搜算法,它是一种用于搜索在图中最短路径的算法。广搜算法从初始状态开始,扩展最近的节点,直到到达终止状态。在这道题中,我们使用了双端队列和集合来存储和跟踪已访问的节点。双端队列是一种特殊的队列,它允许从两端添加和删除元素,这使得BFS算法更加高效。集合是一种无序的数据结构,它可以用来存储唯一的元素,这样就可以避免重复访问节点。
在本题中,小青可以选择步行或公交的方式,步行的速度是每分钟一个节点,公交的速度是每分钟两个节点。为了使小青到达小码的家的最短时间,我们将公交的节点数乘以2,然后进行广搜搜索,寻找最短路径。
总之,BFS算法是一种非常有效的图搜索算法,它可以用来解决很多图搜索问题,而且可以使用双端队列和集合来存储和跟踪已访问的节点,从而提高搜索效率。