当青训营遇上码上掘金
题目描述
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
思路解析
对于每次向外扩展有两种方式,一种是向相邻两个地点扩展,即和另一种是向地点扩展。(为当前所在位置)
那么我们会发现对于这个问题我们只需要记录每个地点第一次到达的时间即可处理出到达每个地点的最短时间。
所以我们可以使用来对问题进行处理。
以点为起始点,放入队列,按照两种方式向外扩展,记录每个地点首次到达的时间即为最短时间,当到达时便可结束。
以下使用实现示例代码。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int vis[maxn],dis[maxn];
queue<int>q;
int main(){
int n,k;
cin>>n>>k;
memset(dis,-1,sizeof dis);
q.push(n);
dis[n]=0;
while(q.size()){
int x=q.front();
q.pop();
if(x==k)break;
if(!(~dis[x-1])&&x-1>=k)q.push(x-1),dis[x-1]=dis[x]+1;
if(!(dis[x+1])&&x+1<=k)q.push(x-1),dis[x-1]=dis[x]+1;
if(!(dis[x*2])&&x*2<=k)q.push(x-1),dis[x-1]=dis[x]+1;
}
cout<<dis[k]<<endl;
}