寻友之旅

75 阅读2分钟

当青训营遇上码上掘金。

题目

小青要找小码去玩,他们的家在一条直线上,当前小青在地点 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])
}