当青训营遇上码上掘金
-
主题 3:寻友之旅
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
本题是经典的BFS(广度优先搜索)题目,使用广度优先搜索可以找出最短路径。
借助队列和标志结点是否已访问的数组实现BFS。
标记某结点已访问,说明到达该结点的最短路径已找到,不必再更新其最短路径。
伪代码
先将N和当前位置分钟数min=0入队
第一次遍历,队头出队,判断当前位置是否和小码的相同,如果是则直接返回当前分钟数;反之判断该队头可能的下一步nextX(X-1、X+1、X * 2),是否已经访问过,如果没有访问过,并且下一步符合0<=nextX<=100000,如果是,则将当前位置的分钟数+1,入队
第二次遍历,队头出队,判断当前位置是否和小码的相同,如果是则直接返回当前分钟数;反之判断该队头可能的下一步nextX(X-1、X+1、X * 2),是否已经访问过,如果没有访问过,并且下一步符合0<=nextX<=100000,如果是,则入队,则将当前位置的分钟数+1,入队
......
第n次遍历,队头出队,判断当前位置是否和小码的相同,如果是则直接返回当前分钟数;反之判断该队头可能的下一步nextX(X-1、X+1、X * 2),是否已经访问过,如果没有访问过,并且下一步符合0<=nextX<=100000,如果是,则入队,则将当前位置的分钟数+1,入队
示例数据N=1,K=3
下图的最上方为队列内容,每个格子都是一次遍历入队的情况
蓝字为入队,绿字为出队,红字为不符合入队要求的可能下一步,黑色字体为当前入队结点的分钟数
最后画了一个树状图,方便理解。
- 1入队
- 1出队,检测1是否等于K,0、2入队
- 0出队,检测0是否等于K,没有符合要求的下一步
- 2出队,检测2是否等于K,3、4入队,1不符合要求
- 3出队,此时检测到3==K,找到最短路径,分钟数为2
代码
定义一个结构体,里面包含当前位置和到达当前位置所消耗的分钟数(到达当前位置的最短路径),使用一个队列,队列存放前面定义的结构体,定义一个标记结点是否已经访问过的数组visit[MAXN+5],MAXN==100000