zoukankan      html  css  js  c++  java
  • 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
    ",f[k]-1);
        }
    }
    

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

  • 相关阅读:
    python_58_装饰器1
    python_57_高阶函数
    python_56_递归
    python_55_局部和全局变量
    python_54_函数调用函数
    python_53_函数补充
    python_52_函数返回值2
    mysql 使用 GROUP BY 时报错 ERROR 1055 (42000)
    sql之left join、right join、inner join的区别
    C++ 函数的重载和参数默认值
  • 原文地址:https://www.cnblogs.com/ShuraK/p/8471496.html
Copyright © 2011-2022 走看看