农夫知道一头牛的位置,想要抓住它。
农夫和牛都位于数轴上,农夫起始位于点 N,牛位于点 K。
农夫有两种移动方式:
从 X 移动到 X−1 或 X+1,每次移动花费一分钟
从 X 移动到 2∗X,每次移动花费一分钟
假设牛没有意识到农夫的行动,站在原地不动。
农夫最少要花多少时间才能抓住牛?
输入格式
共一行,包含两个整数N和K。
输出格式
输出一个整数,表示抓到牛所花费的最少时间。
数据范围
0≤N,K≤105
输入样例:
5 17
输出样例:
4
思路分析
宽度优先队列最短路模型,就是更新d数组,记录各个点到起点的距离,当发现终点的时候,就把这个值返回。所以这个bfs的根本作用就是更新这个d数组,更新d数组的作用是找到终点d的值,也就是最短的距离。入队的同时更新d数组,出队是为了入队。
AC代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int n,k;
int d[maxn];
int bfs(){
memset(d,-1,sizeof d);
int q[maxn],tt=-1,hh=0;
q[++tt]=n,d[n]=0;
while(tt>=hh){
int t=q[hh++];
if(t==k) return d[t];
if(t*2<=2*k&&d[t*2]==-1){
d[t*2]=d[t]+1,q[++tt]=t*2;
}
if(t+1<=2*k&&d[t+1]==-1){
d[t+1]=d[t]+1,q[++tt]=t+1;
}
if(t-1>=0&&d[t-1]==-1){
d[t-1]=d[t]+1,q[++tt]=t-1;
}
}
return -1;
}
int main(){
scanf("%d %d",&n,&k);
printf("%d",bfs());
return 0;
}
要点分析
要注意边界,这个题目看似没有边界,世界上边界是[0,2k]。因为n和k都是非负整数,而且当这个人的起点在终点右边的时候,不可能跑到终点左边,所以是不可能小于0的;
当我在终点的右边的时候,我不可能继续+1或者2,因为这样做了还得回来,所以我+1或2只能在k的左边。所以不可能超过2k。所以就确定了边界。不确定边界的话,就会一直有点进队列,就会死循环下去。