Problem Description
Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.
* Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute
* Teleporting: FJ can move from any point X to the point 2 × X in a single minute.
If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?
Input
Line 1: Two space-separated integers: N and K
Output
Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.
Sample Input
5 17
Sample Output
4
Hint
The fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes.
Source
Recommend
teddy | We have carefully selected several similar problems for you: 2102 1372 1240 1072 1180
思路:一开始特别天真的写了DFS 各种剪枝 回溯 ,显而易见的会T...所以 学了下BFS
在此感谢二位聚聚的帮助(@zly gxy) 如聚聚所说,DFS是时间换空间 BFS是空间换时间
在DFS中如果边界和结束条件(或无效步骤过多)控制不好会T,而在BFS中如果控制不好则会M
言归正传,此题还是比较简单的,用结构体记录数与次数,详情请见代码
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <cstring>
#include <queue>
#define MAXN 100000
using namespace std;
typedef long long ll;
ll n,k;
bool R[MAXN+5]; //标记数组
struct Why
{
ll num,ans; //num表示数 ,ans表示到此数的次数
};
ll bfs(ll a,ll b)
{
queue<Why>T; //开创队列
Why temp; //把初值压入队列
temp.num=a;
temp.ans=0;
T.push(temp);
while(!T.empty()) //检测非空
{
Why K;
K=T.front(); // 取队首,方便后面使用
if(K.num==b) //检测是否是想要的结果
{
return K.ans;
}
else
{
if(K.num+1<=MAXN&&R[K.num+1]==0)
{
R[K.num]=1; //标记已经走过(不然会M)
Why temp;
temp.ans=K.ans+1;
temp.num=K.num+1;
T.push(temp); //压队
}
if(K.num-1>=0&&R[K.num-1]==0)
{
R[K.num]=1;
Why temp;
temp.ans=K.ans+1;
temp.num=K.num-1;
T.push(temp);
}
if(K.num*2<=MAXN&&R[K.num*2]==0)
{
R[K.num]=1;
Why temp;
temp.ans=K.ans+1;
temp.num=K.num*2;
T.push(temp);
}
T.pop(); //弹出队首
}
}
return 0;
}
int main()
{
ios::sync_with_stdio(false);
while(cin>>n>>k,!cin.eof())
{
memset(R,0,sizeof(R)); //标记数组一定要每次清零
cout<<bfs(n,k)<<endl;
}
return 0;
}