当青训营遇上码上掘金。
题目
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式 可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
问题:请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
思路
如果他在小青家前面,公交不能后退,只能步行,那么最短时间就是n - i
如果在小青家N点后面,则可以坐公交:
- 如果是偶数位置,那么它可以直接由前面的点坐公交到达时间最短,状态转移为res[i] = res[i/2] + 1;
- 如果是奇数位置,那么它前后两格距离是偶数位置,状态转移为res[i] = min(res[i-1] + 1, res[(i+1)/2] + 2)。
从0开始遍历到,输出到达点的最短时间。
小青和小码的家在一条直线上,可以用一维的动态数组求解,我们定义一个数组res,res[i]表示从小青家也就是n点到小码家k点的最短时间,小青出行有两种方式:1、步行,一分钟往前后移动一格,2、公交,一分钟移动两倍所在位置值的距离且不能后退.
**代码 **
func min(x, y int) int {
if x < y {
return x
}
return y
}
func main() {
var n, k = 0, 6
res := make([]int, k+1)
for i := 0; i < k+1; i++ {
if i <= n {
res[i] = n - i
} else {
if i%2 == 0 {
res[i] = res[i/2] + 1
} else {
res[i] = min(res[(i+1)/2]+2, res[i-1]+1)
}
}
}
fmt.Println("最短时间为:", res[k])
}