题目描述
已知你的位置是N,目的地的位置是K。为了去目的地,你有两种移动方式:走路或者坐公交。
走路:你可以从位置X移动到X+1或者X-1
搭公交车:你可以从位置X移动到2X
每次走路或者搭公交车所需要的时间都是1分钟,你想尽快到达目的地,所需的时间是多少呢?
输入
多组数据。
对于每组数据,输入一行,分别是N和K(0<=N,K<=100,000)
输出
对于每组数据,输出一行,所需时间
样例输入
5 17
样例输出
4
【思路】因为每次移动的代价是相同的,而广度优先搜索算法在权值一样时的解即为最佳解,所以此题用广度优先搜索算法。将每次的选择看成一个三叉树,即-1,+1,*2。初始位置为树的根结点,然后依次访问当前结点的三个孩子 ,每访问一个结点将该结点放入队列以实现广度优先搜索,得到最佳解时跳出循环。
#include<iostream>
#include<string.h>
#include<queue>
#include <algorithm>
using namespace std;
int main(void) {
int n,k;
while(scanf("%d%d",&n,&k)!=EOF){//n为初始位置,k为目的地
int dist[100001];
memset(dist, 0,sizeof(dist));
//设置访问标记数组,初始值为0,表示未访问
bool visited[100001];
memset(visited,false,sizeof(visited));
//stl创建队列,用于存放访问的结点,并将根结点入队,标记根结点已访问
queue<int> Q; //每次将当前位置入队,若队头元素值为k即到了目的地,dist数组存放路径长度
Q.push(n);
visited[n]=true;
int temp;
while(!Q.empty()){
n = Q.front();
Q.pop();
if(n == k){
printf("%d\n", dist[n]);
break;
}
//将所有未访问的结点入队
temp = n+1;//坐标前进一步
if(visited[temp] == false && temp <= 100000){
visited[temp] = true;//标记访问
dist[temp] = dist[n] + 1;//路径长度
Q.push(temp);//当前位置+1的结果入队
}
temp = n-1;//坐标后退一步
if(visited[temp] == false && temp >= 0){
visited[temp] = true;//标记访问
dist[temp] = dist[n] + 1;//路径长度
Q.push(temp);//当前位置-1的结果入队
}
temp = n*2;//坐标乘以2
if(visited[temp] == false && temp <= 100000){
visited[temp] = true;//标记访问
dist[temp] = dist[n] + 1;//路径长度
Q.push(temp);//当前位置*2的结果入队
}
}
}
return 0;
}