当青训营遇上码上掘金
题目如下:
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 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))