Description
农民John刚刚获悉一头逃跑的牛的位置,打算立刻就去把它抓回来。John和牛都站在一条直线上,开始时John位于坐标点N上( 0 ≤ N ≤ 100,000 ),牛位于坐标点K上( 0 ≤ K ≤ 100,000 )。John有两种行动方式:步行和瞬移(这种技能不是一般群众具备的)。
步行:John花一分钟由任意点X移动到点X-1或点X+1。
瞬移:John花一分钟由任意点X移动到点2*X。
假设牛不知道John来抓它,一直站在原地吃草。问John最少需要花多少分钟才能抓到它?
Input
有多个测试用例,每个用例一行,有两个整数:N和K,用空格分隔。最后一行是两个 -1,不用处理。
Output
为每个用例输出一个整数(单独占一行):John抓住逃跑的牛最少需要的时间,以分钟算。
Sample Input
5 17
-1 -1
Sample Output
4
Source
#include <bits/stdc++.h>//如果不用c++输入则调用#include<stdio.h>与#include<string.h>
using namespace std;
#define max 100006
int main()
{
int N,K;
int a,b,que[max],time[max],head,tail;
/*time数组(用于存放到达结点(即坐标)的时间),一个队列(queue)及队头(head)队尾(tail)*/
int visited[max];
while(cin>>N>>K)
{
if(N<0||K<0) break;
time[K]=-1;///假设到达牛所在坐标的时间为-1(即结点k的值为-1)
memset(visited,0,sizeof(visited));///将所有坐标点的入队状态用0标记,表示未入队
visited[N]=1,time[N]=0;
que[0]=N,head=0,tail=1;//将n插入队列,此时队头的值为0,队尾的值为1
while(head<tail&&time[K]==-1)///当队头不等于队尾(即队列不为空)及k的值未被改变时,执行循环
{
a=que[head];
head++;
if(a+1>=0&&a+1<max&&visited[a+1]==0)/*判断子结点a+1是否超越坐标范围及入队状态*/
{
visited[a+1]=1,time[a+1]=time[a]+1;/*标记a+1已入队,其值为父结点的值加1*/
que[tail]=a+1;/*将a+1插入队列*/
tail++;///队尾后移,同时判断队尾是否需要循环
if(tail==max)
tail=0;
}
if(a-1>=0&&a-1<max&&visited[a-1]==0)
{
visited[a-1]=1,time[a-1]=time[a]+1;
que[tail]=a-1;
tail++;
if(tail==max)
tail=0;
}
if(2*a>=0&&2*a<max&&visited[2*a]==0)
{
visited[2*a]=1,time[2*a]=time[a]+1;
que[tail]=2*a;
tail++;
if(tail==max)
tail=0;
}
}
cout<<time[K]<<endl;
}
return 0;
}