当青训营遇上码上掘金
题目
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
解题思路
读题过后,需要处理输入的特殊情况,由于公交不可以向后走,当N >= K时,小青只能选择向后走,此时所需时间是N-K。
当N < K时
定义int数组steps,steps[i]表示小青从i处到达K处需要多少步,我们考虑最后一步到达i处,这时只有两种情况:
- 方法1:从i-1处走路到达i处
- 方法2:从i/2处坐公交到达i处
当i为奇数时只能选择方法1,这时思路就清晰了,要求出到达K处的最小步数,即steps[K],当K为奇数时,只需求出steps[K-1]+1;当K为偶数时,需求出steps[K-1]+1和steps[K/2]+1的最小值,以此递推。
源代码:
package main
import "fmt"
var N, K int
func main() {
fmt.Scan(&N, &K)
ans := returnMinSteps(N, K)
fmt.Println(ans)
}
func min(num1, num2 int) int {
if num1 < num2 {
return num1
}
return num2
}
func returnMinSteps(n, k int) int {
var steps []int
// 初始化steps数组,如果目的地在朝数值递减的方向,小青只能走路
for i := 0; i <= n; i++ {
steps[i] = n - i
}
for i := n + 1; i <= k; i++ {
if i%2 != 0 {
steps[i] = steps[i-1] + 1
} else {
steps[i] = min(steps[i-1]+1, steps[i/2]+1)
}
}
return steps[k]
}