捕牛记-广搜

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

USACO 2007 Open Silver

#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;
}





发布了35 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Honeycomb_1/article/details/79234255