Descriptions:
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 minuteTeleporting: 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.
先解释一下意思吧 农夫约翰获知了一头逃走的牛的位置,想要将它立即抓住。他从数轴上的一个点 N (0 ≤ N ≤ 100,000) 出发,牛位于相同数轴上的点 K (0 ≤ K ≤ 100,000)。农夫约翰有两种前进方式:行走和神行。
行走:农夫约翰可以从任何 X 移动到点 X - 1 或 X + 1,只需要一分钟;神行:农夫约翰可以从任何点 X 移动到点 2 × X,也只需要一分钟。 如果那头逃走的牛并不知道对它实施的抓捕行动,因此完全不移动,那么农夫约翰花多少时间可以抓住这头牛? Input 第一行包含两个以空格分隔的整数: N 和 K Output 第一行输出农夫约翰抓住逃走的牛,所花费的最短时间 (分钟)。 Hint 农夫约翰抓住逃走的牛的最快方式,是按如下路径移动:5-10-9-18-17,这花费了 4 分钟。这题我的想法就是bfs,加个优先队列吧,毕竟求最小话费时间,优先队列是一定没有错的,个人习惯写法。大致判断一下农夫下一步该走到哪里,那个地方是否满足2个条件:是否在0-100000之间;这个点是否走过。符合这两点就能入队了。break的判断就是,农夫现在的地方等于牛的地方。
上代码:
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <queue> #include <string> #include <cstring> #include <map> #include <stack> #include <set> using namespace std; int N,K; int vis[100010];//路径判断是否走过 struct node { int n,k;//n为现在的地方,k为牛的地方 int step;//步数即时间 friend bool operator<(node a,node b)//步数小的现出来,即时间少 { return a.step>b.step; } }; priority_queue<node>q; void bfs() { node now;//初始化now now.n=N; now.k=K; now.step=0; q.push(now); while(!q.empty()) { node mid=q.top(); q.pop(); if(mid.n==mid.k)//农夫现在的地方等于牛的地方,即找到牛了 { cout << mid.step <<endl; return; } //农夫的三种走法判断是否符合题意 if(mid.n+1>=0&&mid.n+1<=100000&&!vis[mid.n+1]) { node last;//更新队列 last.k=K; last.n=mid.n+1; last.step=mid.step+1;//步数+1 vis[mid.n+1]=1;//标记路径 q.push(last);//入队 } if(mid.n-1>=0&&mid.n-1<=100000&&!vis[mid.n-1]) { node last; last.k=K; last.n=mid.n-1; last.step=mid.step+1; vis[mid.n-1]=1; q.push(last); } if(mid.n*2>=0&&mid.n*2<=100000&&!vis[mid.n*2]) { node last; last.k=K; last.n=mid.n*2; last.step=mid.step+1; vis[mid.n*2]=1; q.push(last); } } } int main() { memset(vis,0,sizeof(vis));//初始化路径都为0,即没有走过 cin >> N >> K; vis[N]=1; bfs(); return 0; }