抓住那头牛

【题目描述】

农夫知道一头牛的位置,想要抓住它。农夫和牛都位于数轴上,农夫起始位于点N(0 <= N <= 100000),牛位于点K(0 <= K <= 100000)。农夫有两种移动方式:

(1)从X移动到X-1或X+1,每次移动花费一分钟;
(2)从X移动到2*X,每次移动花费一分钟; 
假设牛没有意识到农夫的行动,站在原地不动。农夫最少要花多少时间才能抓住牛?

【输入描述】

输入两个整数N、K。

【输出描述】

输出一个整数,农夫抓到牛所要花费的最小分钟数。

【样例输入】

5 17

【样例输出】

4

源代码:

#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
queue <int> h;
int m,n,i[100001];
int main() //DFS搜不出来的,还是叫隔壁的BFS开坦克吧。
{
    memset(i,0x3f,sizeof(i));
    scanf("%d%d",&n,&m);
    h.push(n);
    i[n]=0;
    while (h.size())
    {
        int t=h.front();
        h.pop(); //别忘记删除队首。
        if (t==m)
          break;
        if (t<100000&&i[t+1]>i[t]+1) //注意边界。
        {
            i[t+1]=i[t]+1;
            h.push(t+1);
        }
        if (t>1&&i[t-1]>i[t]+1)
        {
            i[t-1]=i[t]+1;
            h.push(t-1);
        }
        if ((t<<1)<=100000&&i[t<<1]>i[t]+1)
        {
            i[t<<1]=i[t]+1;
            h.push(t<<1);
        }
    }
    printf("%d",i[m]);
    return 0;
}

/*
    思想总结:
        譬如这种很难精确下去的题目,BFS就大有用场了。
        找到点后立即结束就可以了,因为越往后步数就越多。
        i[]数组记录到节点的最少步数,此为剪枝的精髓。
*/
原文地址:https://www.cnblogs.com/Ackermann/p/5759626.html