当青训营遇上码上掘金
主题3——寻友之旅
题意
点A和点B在一个坐标轴上,要从点A到达点B,每次行动只能前进一格或后退一格或移动到2*X(X为当前位置),问最小移动次数
题解
从点A直接开始搜索,用bfs来模拟最短路操作,设起始点的dist为0,将其放到一个队列中,其可以到达的下一个点按顺序放入队列中,并将这些点的dist设为源点的dist+1。若某个点已在之前到达过,则不考虑更新这个点,这样可以保证这是第一次到达这个点时就是到达该点的最短路径。
这里的st数组表示该点是否已经到达过,若为true则到达过,false则未到达
dist数组则存储第一次到达这个点所需要的移动次数,即最短路长度
在bfs中,使用q数组模拟队列,tt模拟队头,hh模拟队尾,每次存入一个新节点时则让tt自增1,存入该位置,每次取出一个节点时则先取出hh位置的数,再让hh自增1,表示弹出该值
然后就分为三种情况,分别是向前走一格、向后走一格、向x * 2处走,每次都让目的地的dist数组等于位置x的dist数组 + 1,表示从x移动到该位置需要一次操作,再将该位置存入队列中以便下次更新
package main
import (
"fmt"
)
var st [200010]bool
var n, k int
var dist [200010]int
func bfs(){
var q [200010]int
var tt,hh int
tt = -1
hh = 0
tt += 1
q[tt] = n
st[n] = true
for ;tt >= hh;{
var x int
x = q[hh]
hh += 1
if x + 1 <= 100000 && !st[x + 1]{
dist[x + 1] = dist[x] + 1
st[x + 1] = true
tt += 1
q[tt] = x + 1
}
if x - 1 >= 0 && !st[x - 1]{
dist[x - 1] = dist[x] + 1
st[x - 1] = true
tt += 1
q[tt] = x - 1
}
if x * 2 <= 100000 && !st[x * 2]{
dist[x * 2] = dist[x] + 1
st[x * 2] = true
tt += 1
q[tt] = x * 2
}
}
}
func main() {
fmt.Scan(&n)
fmt.Scan(&k)
bfs()
fmt.Printf("%d",dist[k])
}