寻友之旅

64 阅读2分钟

当青训营遇上码上掘金

题目如下:

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

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

从题中可以得出,对于每一分钟,若之前所在点为n,则可以到达的点为n+1,n-1,2xn.很容易我们便可以想到对每一分钟所到的点进行记录,若存在小码所到的点,则该分钟为最先达到的时间。由此,可以考虑使用bfs进行操作

想到bfs后,我们便要去考虑怎样优化,对于该问题,我们将所有点视为一个数轴。 若采用+1的步骤执行,则当前点n一定是小于K的,对于大于K的点,我们可以不考虑这步 若采用-1的步骤执行,则当前点n一定是大于0的。因为题中给出了n,k都大于0; 如采用x2的步骤执行,则我们应当先执行-1步骤再x2,若先x2再-1,则可能会多走。

结合上述的考虑,并结合的bfs模板,则可以轻松写出解决方案

代码如下

c++

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N=1e5+10;

int n,k;
int q[N];
int dist[N];

int bfs()
{
    memset(dist,-1,sizeof dist);
    dist[n] = 0;
    q[0] = n;
    
    int hh = 0,tt=0;
    while (hh<=tt)
    {
        int t = q[hh++];
        if(t==k) return dist[k];
        if(t+1 <N && dist[t+1]==-1)
        {
            dist[t+1] = dist[t]+1;
            q[++tt] = t+1;
        }
        if (t-1>=0&& dist[t-1]==-1)
        {
            dist[t-1] = dist[t]+1;
            q[++tt] = t-1;
        }
        if(t*2<N&& dist[t*2]==-1)
        {
            dist[t*2] = dist[t]+1;
            q[++tt] = t*2;
        }
    }
    return -1;
}

int main()
{
    cin>>n>>k;
    
    cout<<bfs()<<endl;
    
    return 0;
}


python

n,k = list(map(int,input().split()))
N = 200010
dist = [-1]*N
q = [0]*N

def bfs(n,k):
    global N,dist
    dist[n] = 0
    hh = 0
    tt = 0
    q[0] = n
    while hh<=tt:
        n = q[hh]
        hh+=1
        if n == k :
            return dist[n]
        if n+1 <= k and dist[n+1]==-1:
            dist[n+1] = dist[n]+1
            tt +=1
            q[tt] = n+1
        if n-1>= 0 and dist[n-1] == -1:
            dist[n-1] = dist[n]+1
            tt+=1
            q[tt] = n-1
        if n*2 <N and dist[2*n] == -1:
            dist[2*n] = dist[n]+1
            tt+=1
            q[tt] = 2*n

print(bfs(n,k))