当青训营遇上码上掘金
题目:
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
解题思路:
小青到达K点存在两种情况:
- 正常到达
- 超过折返
正常到达中又存在选择问题,如果小青乘车之后,距离K点只剩下步行两次的路程,需要选择步行来到达K点。 只有当小青乘车加上折返的时间要小于小青直接步行到达K点的时间才会存在超过折返情况。 题目要求是求出到达K点最短时间,那么乘车肯定是优先选择(当N为0时不可乘车),当N乘车之后超过K点才需要我们判断决策是步行直接到达,还是超过折返。可以直接暴力解题
暴力法代码实现如下
package main
import "fmt"
func main() {
var N, K int
time := 0
fmt.Scanln(&N, &K)
if N < 0 || K > 100000 {
return
}
for N != K {
//未超过终点
if N < K {
N = max(N, K)
println("N : ", N)
time++
println("time : ", time)
}
//超过终点
if N > K {
time += N - K
println("time2 : ", time)
break
}
}
//输出结果
fmt.Println(time)
}
// 未达到终点之前比较两种方式,谁移动更远
func max(X, K int) int {
//步行距离更远时
if X+1 > X*2 {
return X + 1
} else {
//当乘车会超过终点
if X*2 > K {
time1 := K - X //计算步行时间
time2 := X*2 - K + 1 //计算乘车后步行返回K的时间
//选择时间更短的方式
if time1 < time2 {
println("超过终点,选择步行")
return X + 1
} else {
println("超过终点,选择乘车")
return X * 2
}
} else { //乘车不会超过终点
return X * 2
}
}
}