当青训营遇上码上掘金
主题 3:寻友之旅
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
作者:青训营官方账号
链接:juejin.cn/post/718775…
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
解题思路
此题可分为4种情况
-
输入的N小于0,K大于100000,不符合题目要求,直接返回-1
-
输入的N大于K,因为公交车不能向后行驶,小青故只能步行达到小码家,所使用的时间为(N - K)
-
输入的N等于K,小青家与小码家在同一节点,故使用时间为0
-
输入的N小于K,最显眼的题目要求,在同一时间上,坐公交比步行快许多,所以我们用一个贪心算法的思想,只坐公交,但是有一个特殊情况,当N为0时,坐公交还是在原地,所以若N为0,则步行一次。之后再坐公交,当在下一次坐公交可以超过K点的距离时,要进行一个判断,若提前下车,步行到K点的时间小于坐公交到超过K点的距离,然后步行返回的时间,则提前下车,否则,坐公交后步行返回。
代码实现
import java.util.*;
public class Main {
public static void main(String []args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
int K = scanner.nextInt();
int time = selectRoad(N, K);
System.out.println(time);
}
public static int selectRoad(int N,int K){
if(N < 0 || K > 100000) {
return -1;
}
int time = 0;//计数时间
//如果小码家住在小青家后面,则只能步行
if(K < N){
time = N - K;
return time;
}else if (N == K){//若两个人就住在同一节点,就直接返回0,不用走
time = 0;
return time;
}else {//利用贪心算法的思想,时间一样,尽量坐公交,用N的变化来慢慢靠近K
while (N < K){
//当结点N为0时,只能走路
if(N == 0){
N = 1;
time++;
continue;
}
//如果N不为0就开始坐公交,坐公交到提前一站要考虑是直接坐过,走路回退时间短,还是提前下车走路到达时间短
if(N * 2 <= K){
N *= 2;
time++;
}else {//如果此时坐公交可以超过了K点,要进行以上注释的考虑
if((K - N) < (N * 2 - K)){//此时可提前下车,走路到K点
time += (K - N);
}else {//
time = time + 1 + (N * 2 - K);
}
N = K;
}
}
return time;
}
}
}