(BFS)Catch That Cow(poj3278)

题目:

农夫知道一头牛的位置,想要抓住它。农夫和牛都于数轴上 ,农夫起始位于点 N(0<=N<=100000) ,牛位于点 K(0<=K<=100000) 。农夫有两种移动方式: 1、从 X移动到 X-1或X+1 ,每次移动花费一分钟 2、从 X移动到 2*X ,每次移动花费一分钟 假设牛没有意识到农夫的行动,站在原地不。最少要花多少时间才能抓住牛?
Input
一行: 以空格分隔的两个字母: N 和 K
Output
一行: 农夫抓住牛需要的最少时间,单位分钟
Sample Input
5 17
Sample Output
4
Hint
农夫使用最短时间抓住牛的方案如下: 5-10-9-18-17, 需要4分钟.

分析与解答

由于无法确定深度,因此用bfs广搜,bfs不需要回溯,是一层一层推进,一直到最后的解


这题有三种情况,后退一步,前进一步,前进二倍当前距离,那我们就层次遍历,每层输入到队列里,输完了就把上一层pop掉,就是不断遍历并且查找,遇到最终结果return并输出time即可
为了减小时间,我们需要判重,每次只入那些曾经没出现过的数。
这一类bfs具体怎么实现,就是先建一个队列,然后把第一个数push里面,只要队列不空,就一直对队列进行出队入队操作。需要有两个变量 m,next;m存的是根结点,每次循环最初需要把他取出,next存的是由根结点+1-1*2从而形成的子结点,我们存子结点时注意判重,不重复我们就push next,并且标记。注意每次操作完之后我们都要检查一下是不是满足最终的结果,如果满足我们直接return就行

代码参考:https://blog.csdn.net/qq_38620461/article/details/78445374

#include<bits/stdc++.h>
using namespace std;
int to[2]={1,-1};
int a,b,sum;
int vis[100000];
struct place
{
    int x,time;
};
int check(place k)
{
    if(k.x<0||k.x>100000||vis[k.x]==1)
        return 0;
    return 1;
}
int bfs(place n)
{
    place m,next;
    queue<place>w;
    w.push(n);
    while(!w.empty()) 
    {
        m=w.front();
        w.pop();
        if(m.x==b)
            return m.time;
        for(int i=0;i<2;i++)
        {
            next.x=m.x+to[i];
            next.time=m.time+1;
            if(next.x==b)
                return next.time;
            if(check(next))
            {
                w.push(next);
                vis[next.x]=1;
            }
        }
        next.x=m.x*2;
        next.time=m.time+1;
        if(next.x==b)
            return next.time;
        if(check(next))
        {
            w.push(next);
            vis[next.x]=1;
        }
    }
    return 0;
}
int main()
{
    int i,j,t;
    place x1;
    while(~scanf("%d %d",&a,&b))
    {
        memset(vis,0,sizeof(vis));
        x1.x=a;
        x1.time=0;
        vis[x1.x]=1;
        sum=0;
        sum=bfs(x1);
        printf("%d\n",sum);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40828914/article/details/81461378
今日推荐