• 简单搜索(BFS Catch That Cow)


    ~~一个常年拒绝思考的混吃等死选手~~

    题目是这样的:

    > Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.
    > Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute
    Teleporting: FJ can move from any point X to the point 2 × X in a single minute.
    If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?

    >Input:
    Line 1: Two space-separated integers: N and K
    Output:
    Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.
    [题目连接](http://poj.org/problem?id=3278)

    某杜一看,不难,就是抓牛嘛,和某杜最擅长的摸鱼没差。
    稍微思考了一会儿发现:不对劲!即使看懂了题目、笔算也能算出来,可是感觉缺少了什么、写不出程序。

    于是某杜带着题请教了教练,没一会儿教练回复了几个词:
    简单搜索、BFS、菜。

    BFS?BFS我懂啊,BFS不是图里面的吗?这题还得用图啊?

    一会儿教练又回了:
    百度去

    某杜百度回来以后大彻大悟:原来是这个意思。

    先上代码:
    ```
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #define max 100005
    using namespace std;
    int n,k;
    struct node{
    int x;
    int step;
    }q[max];
    int flag[max];
    void bfs(){
    int i;
    node now,next;
    int head=0,tail=0;
    q[head].x=n;
    q[head].step=0;
    tail++;
    flag[n]=1;
    while(head<tail){
    now=q[head];
    head++;
    for(i=0;i<3;i++){
    if(i==0){
    next.x=now.x-1;
    }
    else if(i==1){
    next.x=now.x+1;
    }
    else{
    next.x=now.x*2;
    }
    if(next.x<0||next.x>100001){
    continue;
    }
    if(flag[next.x]==0){
    flag[next.x]=1;
    next.step=now.step+1;
    q[tail].x=next.x;
    q[tail].step=next.step;
    tail++;
    if(next.x==k){
    printf("%d ",next.step);
    }
    }
    }
    }
    }
    int main(){
    while(scanf("%d %d",&n,&k)!=EOF){
    memset(flag,0,sizeof(flag));
    if(n>=k){
    printf("%d ",n-k);
    }
    else{
    bfs();
    }
    }
    return 0;
    }
    ```
    有结构体数组、head和tail,是一个队列跑不了,但是先说说这究竟是怎么一回事。
    在某杜的理解下,这类搜索题一共有两个要点:
    **1、上一个状态和下一个状态**
    **2、上一个状态如何变到下一个状态**
    是不是和动态规划有异曲同工之妙,只不过某杜对动态规划的理解还止步于状态和状态转移方程,所以不敢多说什么。硬要说的话应该是**BFS搜索通过略暴力的方式把所有符合条件的情况都算了一遍,直到某一次的运算结果符合了题目的输出要求才停止运算输出结果,这其中由初始状态到目标状态的路子有很多种。**
    打个比方,如果没有题目限制,由2到10,我可以每次加1加8次,我可以每次加2加4次,我还可以每次乘5乘一次。
    然而BFS搜索题总会给你一个或者几个题目要求,比如要求你只能每次加1和每次加2或者只能每次加1和每次乘5。

    理解了很好理解的这些以后再看题简直太简单,题目说的清清楚楚,FJ每次可以往前走1或者往后退1或者一次乘2。

    然后就是存储和使用数据的形式,其实也不难想,我**需要用到现在的状态去算下一个状态**,拿题目来说,刚开始FJ站在5,FJ往前走一步走到了6,FJ往后退一步退到了4,FJ Teleporting 了一下到了10,然后把6、4、10这三个量存一下,5就不需要了。这很明显符合队列的存取特征,那就用队列呗。

    还有一些细节,比如FJ已经在0了,如果再往后退1显然不符合常理,再比如FJ Teleporting过了头,Teleporting出了最大范围,这也不需要再算了,直接砍掉。

    还有假如FJ已经由5通过Teleporting到过了10,那么FJ就不需要再记录由5通过每次走1走到10花了多少次,因为第二次到10肯定比第一次用的步数多。

    理解了这一道题以后,某杜又找了一些别的简单搜索题写,差不多就是换个皮,做法和抓牛一样。

    某杜学会了,某杜企图向教练炫耀——教练说,还有一堆儿搜索进阶题呢,慢慢写吧。。

  • 相关阅读:
    图论初步
    分块和块状链表
    线段树入门
    ST表与树状数组
    [luogu P1312]Mayan游戏
    [luoguP4139]上帝与集合的正确用法


    电解质
    无机盐
  • 原文地址:https://www.cnblogs.com/dujiangyue/p/10003529.html
Copyright © 2020-2023  润新知