很荣幸能够参加第五届字节跳动青训营,由于这次报名的是后端,因此我选择了主题3来进行创作。
题目介绍:寻友之旅
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 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步:
int N, K;
cin>>N>>K;
if(N>=K){
cout<<N-K;
}
第二种情况:当N小于K时
当N小于K时,应该尽可能多坐公交来使得时间尽量的短。 假设坐车的时间为a,用while循环对a进行加一操作直到N2^a大于等于K。此时的a刚好使得N2^a大于等于K,即坐过站,而N*2^(a-1)小于K,没有坐过站。
int a=1;
while(N*pow(2,a)<K){
a++;
}
这时就需要判断是坐过K用的时间少还是坐过K前一站用过的时间少,然后返回较少的时间即为所需的最终答案。
int t1 = a-1 + (K-N*pow(2,a-1));
int t2 = a+ (N*pow(2,a)-K);
if(t1>t2){
cout<<t2;
}
else{
cout<<t1;
}