「青训营 X 码上掘金」主题 3:寻友之旅 BFS DFS
当青训营遇上码上掘金
主题 3:寻友之旅
语言: Go
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
一般解答
package main
import "fmt"
func main() {
// 输入n k
var n, k int
_, err := fmt.Scanf("%d%d", &n, &k)
if err != nil {
return
}
// 初始化计数器并循环求解
count := 0
for n != k {
if k > n {
if k%2 == 0 {
k = k / 2
} else {
k = k - 1
}
count++
} else {
k = k + 1
count++
}
}
// 输出计数器结果
fmt.Println(count)
}
BFS解答
func main() {
// 初始化
var n, k int
fmt.Scanf("%d%d", &n, &k)
start := Node{n: n, minute: 0}
// 初始化
queue := []Node{start}
// 初始化
visited := make(map[int]bool)
// 初始化
target := k
// BFS
for len(queue) > 0 {
// Get
node := queue[0]
queue = queue[1:]
// Check
if _, ok := visited[node.n]; ok {
continue
}
// Mark
visited[node.n] = true
// Check
if node.n == target {
fmt.Println("Found target in", node.minute, "minutes")
break
}
// Add
queue = append(queue, Node{n: node.n - 1, minute: node.minute + 1})
queue = append(queue, Node{n: node.n + 1, minute: node.minute + 1})
queue = append(queue, Node{n: node.n * 2, minute: node.minute + 1})
}
}
DFS解答
package main
import "fmt"
func dfs(n, k int, depth int) int {
if n == k {
return depth
}
if n > k {
return dfs(n-1, k, depth+1)
}
if n < k {
return dfs(n+1, k, depth+1)
}
return dfs(n*2, k, depth+1)
}
func minStepsToK(n, k int) int {
if n == k {
return 0
}
minSteps := dfs(n+1, k, 1)
minSteps = min(minSteps, dfs(n-1, k, 1))
minSteps = min(minSteps, dfs(n*2, k, 1))
return minSteps
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func main() {
var N, K int
_, err := fmt.Scanf("%d%d", &N, &K)
if err != nil {
return
}
minutes := minStepsToK(N, K)
fmt.Println(minutes)
}