Catch That Cow_bfs

Catch That Cow

    题目大意:FrammerJohn找奶牛,给出n和k。FJ在n处。每次他可以向左移动一格、向右移动一格或者移动到自己当前格子数乘2的地方。求FJ最少移动多少次。其中,FJ和Cow在数轴上。

    注释:$1<=n,k<=10^5$。

      想法:又是一道bfs裸题。就是通过简单的bfs来找寻最优解。其中,先遍历到的点在后面重新遍历时,所得到的步数一定是更劣的。所以,每个点我们只需要更新一次。我们通过f数组记录f[i]表示从n到i的最小步数。然后,我们可以不另开bool数组,只需要通过判断f数组是否有值即可。这里有一个小技巧,就是我们将f[n]=1,然后输出答案时输出f[k]-1.这样就可以避开n点的错误重新遍历的情况。

    最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
int n,k;
int f[200010];
inline void bfs()
{
    queue<int>q;
    int x;
    q.push(n);
    f[n]=1;//小技巧
    while(!q.empty())
    {
        x=q.front();
        q.pop();
        if(x+1<=2*k&&!f[x+1])
        {
            f[x+1]=f[x]+1;
            q.push(x+1);
        }
        if(x-1>=0/*这里非常重要,搜索中我们习惯在入队时就将不满足题意者去除,而不是在出队时特判*/&&!f[x-1])
        {
            f[x-1]=f[x]+1;
            q.push(x-1);
        }
        if(x*2<=k*2&&!f[x*2])
        {
            f[x*2]=f[x]+1;
            q.push(x*2);
        }
    }
    return;
}
int main(void)
{
    while(~scanf("%d%d",&n,&k))
    {
        memset(f,0,sizeof f);
        bfs();
        printf("%d\n",f[k]-1);
    }
}

 

     小结:错误的点就是没有考虑到遍历时f数组小于零时的越界情况。在入队时处理而不是在出队时特判。

 

posted @ 2018-02-26 09:17  JZYshuraK_彧  阅读(229)  评论(0编辑  收藏  举报