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.
题意:给定两个整数n和k,通过 n+1或n-1 或n*2 这3种操作,使得n==k。输出最少的操作次数。
广度优先搜索实现方法(非递归):
1.设置一个队列Q,从顶点出发,遍历该顶点后让其进队;
2.出队一个顶点元素,求该顶点的所有邻接点(对应于此题即三种走法),
对于没有遍历过的邻接点遍历之,并 让其进队;
3.若队空则停止,否则继续第2步。
注意,在N>K时只能通过不断N-1才能到达K,可直接返回N-K;N=K时,返回0。
利用STL库:
//Memory 820K Times 157MS
#include<iostream>
#include<queue>
#include<utility>
using namespace std;
const int maxn=100010;
int N,K;
bool vis[maxn];
int bfs()
{
if(N>=K) return N-K;//直接返回结果
queue<pair<int,int> > que;//队列记录坐标及对应的步数
vis[N]=true;
que.push(make_pair(N,0));
while(!que.empty())
{
int cur=que.front().first,step=que.front().second;
que.pop();
int next[3];
next[0]=cur+1,next[1]=cur-1,next[2]=cur*2;//三种状态转移方式
for(int i=0;i<3;i++)
{
if(next[i]>=0&&next[i]<maxn&&!vis[next[i]])//剪枝:下一步坐标在范围内且之前没有经过
{
if(next[i]==K) return step+1;//到达终点则返回结果
vis[next[i]]=true;
que.push(make_pair(next[i],step+1));
}
}
}
}
int main()
{
cin>>N>>K;
cout<<bfs()<<endl;
return 0;
}
利用模拟队列(所需存储空间较大,处理速度快):
//Memory: 1056K Time : 16MS
#include<iostream>
using namespace std;
const int maxn = 100010;
struct node {
int num;//坐标
int step;//步数
node(int n = 0, int s = 0)
{
num = n; step = s;
}
}queue[maxn];//模拟队列数组
bool vis[maxn];
int bfs(int n, int k)
{
if (n >= k) return n - k; //特例
//memset(vis, false, sizeof(vis));
//memset(queue, 0, sizeof(queue));
int head, tail;
head = tail = 0;
queue[tail++] = node(n, 0);//初始节点
vis[n] = true;
while (head != tail)
{
node temp = queue[head++];
int next;
for (int i = 0; i < 3; i++)
{
if (i == 0) next = temp.num + 1;
if (i == 1) next = temp.num - 1;
if (i == 2) next = temp.num * 2;
if (next<0 || next>maxn) continue;
if (!vis[next])
{
if (next == k) return temp.step + 1;
vis[next] = true;
queue[tail++] = node(next, temp.step + 1);
}
}
}
}
int main()
{
int n, k;
cin >> n >> k;
cout << bfs(n, k) << endl;
return 0;
}