小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
- 解题思路分析:
- 小青可移动,每次移动可以向前(步行向前一步或者坐车2步)或者向后
- 当N>=K时,最短时间是N-k,此时只能往后走
- 当N<K时,此时可以步走或者乘车
- 采用BFS方式,用distance保存小青到当前节点的最短时间
- flag表示当前节点是否被访问过
- wait保存当前小青可以去到的位置
- 算法实现:
- distacne 数组保存小青到当前位置的最短时间
- flag 数组表示当前位置是否已经处理过
- wait 数组表示小青可以走到的位置
- 初始化阶段:distance 用math.MaxInt32c初始化,根据100001确定
- distance[初始位置]=0
- flag[初始位置] = ture
- wait = append(当前位置加入)
- for wait数组中没有元素{
-
获取当前位置 -
将当前位置剔除 -
判断当前位置+1是否越界{ -
if 比较当前位置 往前走一步 < 下一个可达到位置distance[当前位置+1]{ -
修改distance[当前位置+1],保证distane保存的值是最小的 -
} -
} -
判断当前位置-1是否越界{ -
if 比较当前位置 往后走一步 < 下一个可达到位置distance[当前位置-1]{ -
修改distance[当前位置-1],保证distane保存的值是最小的 -
} -
} -
判断当前位置+1是否越界{ -
if 比较当前位置 往前走2步 < 下一个可达到位置distance[当前位置+1]{ -
修改distance[当前位置*2],保证distane保存的值是最小的 -
} -
distance[K]//表示小青从N出发到达的K的最短距离/1 -
} - }
package main
import (
"fmt"
"math"
)
// 输入两个点的位置,返回到达的最小实际按
func minSecond(n, k int) int {
if n >= k {
// 表示只能步行往后走
return n - k
} else {
// 往前走可以步行或者坐公交车
//distance保存小青到当前节点的最短时间
distance := make([]int, 100001)
for i := 0; i < 100001; i++ {
//100001 在2^32之内
distance[i] = math.MaxInt32
}
distance[n] = 0
//flag标志当前节点是否访问过
flag := make([]bool, 100001)
flag[n] = true
// 保存小青可以到达的位置
wait := make([]int, 0)
wait = append(wait, n)
for len(wait) != 0 {
num := wait[0]
wait = wait[1:]
// 小青往前走,当前位置走一步 小于下一个位置保存的值
if num+1 < 100001 {
if distance[num+1] > distance[num]+1 {
distance[num+1] = distance[num] + 1
}
if !flag[num+1] {
wait = append(wait, num+1)
flag[num+1] = true
}
}
//往后走一步,当前位置 + 1小于 下一个节点值
if num-1 >= 0 {
if distance[num-1] > distance[num]+1 {
distance[num-1] = distance[num] + 1
}
if !flag[num-1] {
wait = append(wait, num-1)
flag[num-1] = true
}
}
// 走两步
if num*2 < 100001 {
if distance[num*2] > distance[num]+1 {
distance[num*2] = distance[num] + 1
}
if !flag[num*2] {
wait = append(wait, num*2)
flag[num*2] = true
}
}
}
return distance[k]
}
}
func main() {
var K, N int
fmt.Println("请输入两个数字K,N")
fmt.Scanf("%d %d", &K, &N)
fmt.Println("达到最短时间为", minSecond(N, K), "分钟")
}