当青训营遇上码上掘金

56 阅读1分钟

很荣幸能够参加第五届字节跳动青训营,由于这次报名的是后端,因此我选择了主题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;
    }