「青训营 X 码上掘金」主题创作活动

86 阅读2分钟

当青训营遇上码上掘金

主题 3:寻友之旅

小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?

输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)

代码思路:

首先 N 可能等于 0,如果一开始就坐公交会在原地不动,因此此时需要花一分钟先往前走一步。我们不知道 N和 K 谁大谁小,如果小码家在小青家前面,即 K>N ,为了更快到达小码家,我们开始坐公交,循环判断下一站是否会坐过小码家,如果没过小码家,则往前进一站,时间加一分钟,如果下一站会坐过站,则从当前站下车。然后判断从当前位置往前走到小码家更快,还是再坐一站公交之后往回走到小码家更快,最后输出总的路程时间;如果小码家在小青家后面,即 K<N ,因为公交不能往回走,小青就只能步行去小码家了。

代码:

package main

import "fmt"

func main() {
   var N int   // 小青家地点
   var K int   // 小码家地点
   var min int // 所需的最短时间
   fmt.Scanf("%d %d", &N, &K)

   // 初始位置在0时,需要步行一步
   if N == 0 {
      N++
      min++
   }
   if K > N {   // 小码家在小青家前面
      // 开始坐公交,如果下一站公交坐过了小码家,则下车
      for {
         if N*2 > K {
            break
         }
         N = N * 2
         min++
      }
      // 判断从当前位置往前走到小码家更快,还是先坐公交再往回走更快
      if K-N <= N*2-K {
         min += K - N
      } else {
         min += N*2 - K + 1
      }
   } else {  // 小码家在小青家后面
      min += N - K
   }
   // 输出最短时间,单位为分钟
   fmt.Println("小青到小码家所需的最短时间(min):", min)
}

运行结果:

image.png

路线:0 - 1 - 2 - 4 - 8 - 9 - 10 - 11 总用时7min

image.png

路线:2 - 4 - 8 - 16 - 15 - 14 总用时5min

image.png

路线:14 - 13 - 12 - 11 - 10 总用时4min

经过验证,代码思路没有问题,可以快速算出小青最快到达小码家的时间。