第一次广搜!HDU1548--A Strange Lift

一上来看见题目就用了深搜(因为只会深搜)果断内存超限(据说时间也会超限)无奈只好开始用广搜

其实广搜的思路和深搜有很多类似的地方 不过实现的过程中用到了队列 因此有点难以理解(好吧我个人认为)

这题是最基本的广搜了 只是一个二叉树

所以先画个二叉树出来看一下广搜的顺序

每一个节点下一层的节点入队之后就把这个节点出队

 

对每一个节点 bfs的顺序是这样的

1.将这个节点的左节点入队(要判断左节点是否已经入队以及是否合适)

2.将这个节点的右节点入队(同样也要盘算右节点是否已经入队以及是否满足条件)

3.判断该节点是否满足条件 如果满足 就return(这时候一定是最短路径因为是一层一层分析的)

4.将该节点出队

 

当所有的节点都出队时说明已经把所有可能的路径都遍历了一遍(有关结束时机的判断还是有点疑问:这个题目当中是当没有合适的子节点时队列就空了 那么有没有可能出现超限或者死循环的情况呢?)

 

下面贴代码(模仿的)

# include<iostream>
# include<queue>

using namespace std;

const int MAX_NUM = 205;

struct node
{
    int floor;
    int step;
};

queue<node>note;
int vis[MAX_NUM];
int k[MAX_NUM];
int A,B, N;

struct node temp,m;

int bfs()
{
    struct node start;
    start.floor = A;
    start.step = 0;

    note.push(start);
    vis[start.floor] = 1;

    while (!note.empty())//结束的时机要想清楚
    {
        temp = note.front();//临时变量的引入,使程序逻辑性更清晰
        
        int up = temp.floor + k[temp.floor];
        if (up<=N&&vis[up]==0)
        {
            vis[up] = 1;
            m.floor = up;
            m.step = temp.step + 1;
            note.push(m);
        }
        int down = temp.floor - k[temp.floor];
        if (down > 0 && vis[down] == 0)
        {
            vis[down] = 1;
            m.floor = down;
            m.step = temp.step + 1;
            note.push(m);
        }

        if (temp.floor == B)
        {
            return temp.step;//不用考虑比较最小路径 这是和深搜不同的一点
        }

        note.pop();
    }

    return -1;
}

int main()
{
    while (1)
    {
        cin >> N;
        if (N == 0)
            break;
        cin >> A >> B;
        for (int i = 1; i <= N; i++)
        {
            cin >> k[i];
        }

        memset(vis, 0, sizeof(vis));
        while (!note.empty())
        {
            note.pop();
        }
        /*将队列和访问标记初始化*/

        cout << bfs() << endl;
    }

    return 0;
}

算法的路还有很长 搜索只是刚刚入门啊!

 

posted @ 2015-12-11 21:52  DigitalHermit  阅读(189)  评论(0编辑  收藏  举报