Description
林大的松树水平排成一行,每棵松树有1个编号,从0开始到n结束! 松树上的松鼠从树A移动到树B是需要下列操作的: (1) 向右走一步,坐标+1; (2) 向左走一步,坐标-1; (3) 使用乾坤大挪移跳一步,坐标乘2; 九条可怜想知道:松鼠从A 树到B 树最少需要移动几步?
Input
输入n,a ,b(0<=a,b<=n<=5000),表示共有n棵松树;小松鼠想要从a到b;
Output
输出最小的跳跃步数!
Sample Input
12 2 9
Sample Output
3
思路:
这种题,广搜,如果重复到一个点时,进行的操作会重复,就标记一下,只进行一次;如果每次进队列需要操作数相当,就不用优先队列。(但我还是用了优先队列)
代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
using namespace std;
const int N =11000;
struct data
{
int no;
int w;
}c;
bool operator >(const struct data &a,const struct data &b)
{
return a.w>b.w;
}
priority_queue<struct data,vector<struct data>,greater<struct data> >q;
int n,a,b,vis[N];
int main()
{
cin>>n>>a>>b;
if(a>b)
swap(a,b);
c={a,0};
q.push(c);
while(!q.empty())
{ c=q.top();
if(c.no==b)
break;
q.pop();
if(c.no+1<=n&&!vis[c.no+1])
q.push({c.no+1,c.w+1}),vis[c.no+1]=1;
if(c.no-1>=0&&!vis[c.no-1])
q.push({c.no-1,c.w+1}),vis[c.no-1]=1;
if(2*c.no<=n&&!vis[2*c.no])
q.push({2*c.no,c.w+1}),vis[c.no*2]=1;
}
cout<<c.w<<endl;
return 0;
}