当青训营遇上码上掘金---寻友之旅

77 阅读2分钟

很开心可以参加此次的 [青训营 X 码上掘金] 主题创作活动,因为没有接触过go语言,在学习go语言上花费了很多时间,终于把寻友之旅这一题基基本本做出来了,有不对的地方希望有大佬可以帮忙指出。

题目介绍


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

请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)

解答过程


思考: 小青需要先乘坐公交车,一直乘坐公交车直到下一趟公交车走到小码家后面的位置,判断是在本站下车还是下一站下车用时更短即可完成题目的要求。

用字母以及数学上的描述即为以下的表达:

分为以下的情况:

  • 当N>=K即小青在小码右边的时候,由于公交车不能往左走,小青只能采用步行的方式前往小码家,故返回N-K 。

  • 当N小于K时,小青为N,小码的位置为K,如果N在K/2和K之间,那N只能到K位置,或者到K/2位置。对于每一次决策,计算之用步行所耗费的时间以及坐一次公交再用步行的时间。再对比到K/2的代价为N-K/2+1(K若为奇数则再加1),到K的代价为K-N。假设N<K/2,那么判定的区间就为K/4到K/2之间,再进行判断。最后获得的答案基础上再加上公交车的时间即为题目要求的结果。

代码展示:

package main

//寻友之路
import (
	"fmt"
)

//求解最少时间的函数
func minTime(N, K int) {
	time := 0
	var bus = 0
	if N > K {
		time = N - K
	} else {
		for N != K {
			if K%2 == 0 {
				walk := K - N
				if K/2-N < 0 {
					bus = N - K/2
				} else {
					bus = K/2 - N
				}
				bus++
				if walk >= bus {
					K = K / 2
				} else {
					K--
				}
			} else {
				K--
			}
			time++
			if N > K {
				time = time + N - K
			}

		}
	}
	fmt.Printf("小青最快的到达时间是%d分\n", time)
}

func main() {
	fmt.Println("测试:")
	minTime(2, 1024)
	minTime(4, 4286)
}