在一个长度为 nn 的坐标轴上,蒜头君想从 AA 点 移动到 BB 点。他的移动规则如下:
- 向前一步,坐标增加 11。
- 向后一步,坐标减少 11。
- 跳跃一步,使得坐标乘 22。
蒜头君不能移动到坐标小于 00 或大于 nn 的位置。蒜头想知道从 AA 点移动到 BB 点的最少步数是多少,你能帮他计算出来么?
输入格式
第一行输入三个整数 nn,AA,BB,分别代表坐标轴长度,起始点坐标,终点坐标。(0 \le A, B \le n \le 50000≤A,B≤n≤5000)
输出格式
输出一个整数占一行,代表蒜头要走的最少步数。
样例输入
10 2 7
样例输出
3
思路: bfs 广度优先搜索 寻找最小的步数 bfs的常规操作 建立标志数据(记录某点是否被访问过) 起点入队 一个判断队列是否为空的循环 取出队首元素 pop队首元素 判断是否已经到达终点 判断各个分支是否满足入队要求.
#include <bits/stdc++.h>
#include <queue>
using namespace std;
int N, a, b, MIN,vis[5050];
struct point{
int x,num;
point(int xx,int tmp_num)
{
x = xx;
num = tmp_num;
}
};
void bfs(int n)
{
queue<point> S;
S.push(point(n,0));
vis[n] = 1;
while(!S.empty())
{
point tmp = S.front();
int tmp_x = tmp.x;
S.pop();
if(tmp_x == b)
{
MIN = tmp.num;
return ;
}
for(int i = 0; i<=2; i++)//枚举三种可能
{
int tmp_xx;
if(i == 0)
tmp_xx = tmp.x - 1;
else if(i == 1)
tmp_xx = tmp.x + 1;
else
tmp_xx = tmp.x * 2;
if(tmp_xx>=0 && tmp_xx<=N && vis[tmp_xx]==0)
{
S.push(point(tmp_xx,tmp.num+1));
vis[tmp_xx] = 1;
}
}
}
}
int main()
{
memset(vis,0,sizeof(vis));
cin>>N>>a>>b;
bfs(a);
cout<<MIN;
return 0;
}