dfs与bfs

简单来说dfs适用于搜索所有情况的解,bfs适用求最小路径;

大家都知道,AiR_H和zbt是好朋友。AiR_H十分喜欢研究历史,这周末他想去山西一个神秘的地方来学习山西的历史,便想拉上zbt一起去。AiR_H对zbt说:山西,因居太行山之西而得名,简称“晋”,东依太行山,西、南依吕梁山、黄河,北依长城,与河北、河南、陕西、内蒙古等省区为界。介于北纬34°34′—40°44′,东经110°14′—114°33′之间,总面积15.67万平方千米…………zbt一脸懵逼,表示,我去,我去还不行吗。他们来到这个无人管理但是有一套自动开门锁门系统神秘的高楼。正在他们在最高楼观光的时候,发现,还有五分钟就要锁门了。被锁住出不去没饭吃饿死的话他们就要变成历史啦!!!zbt十分惊恐,把这栋楼的地图交给AiR_H,让算法大神AiR_H写个程序估计够不够时间。但是AiR_H此时很慌,所以打电话求助你让你帮他算一算至少需要多少时间才能出去。

输入描述

第一行输入一个整数n,代表这栋楼有多少层。AiR_H和zbt就在最高层。(1 <= n <= 100)

下面依次有n个地图(大小都为5 * 5),第i个地图表示第i楼的物品摆放情况

1楼的物品摆放情况

2楼的物品摆放情况

………………

n楼的物品摆放情况

说明书:

'.'代表可以行走的地方

'#'代表障碍物

'@'代表楼梯

1楼'd'字符代表出口

n楼'a'字符代表AiR_H和zbt的位置

相邻两层楼至少有一个楼梯是相同位置的,代表可以从这个位置上楼或者下楼

每个楼梯只能连接x ~ x+1楼或x ~ x-1楼

移动一格算1步,下楼梯算1步

AiR_H和zbt移动的速度为1步/秒

输入保证至少有一条可以出去的通道。

输出描述

输出一个数字代表AiR_H和zbt离开大楼至少需要多少秒。

样例输入

3
..@#.
#.#..
#...d
#.#..
..##.

..@..
#.#.#
#...#
##.##
@....

.....
...#.
..a#.
####.
@....

样例输出

28

来源

中北大学2017年程序设计新生赛

提示

从最高楼开始所花费的步数为12+1+8+1+6,共28步,所以一共花费28秒。

 开始我想过用的dfs,然后,超时;

查了一些资料,才发现dfs时间复杂度高,bfs空间复杂度高,需要记录每个状态;

附上ac代码:

#include<cstdio>
#include<iostream>
#include<cmath>
#include<queue>

using namespace std;
int n;
char map[105][105][105];
int visited[105][105][105];
int dir[4][2]= {1,0,-1,0,0,1,0,-1};

struct node
{
    int n;
    int x;
    int y;
    int step;
} A;

int stn,stx,sty;
int enn,enx,eny;

int main()
{

    scanf("%d",&n);
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<5; j++)
        {
            scanf("%s",map[i][j]);
        }

    }


    for(int i=0; i<5; i++)
    {
        for(int j=0; j<5; j++)
        {
            if(map[0][i][j]=='d')
            {
                enn=0;
                enx=i;
                eny=j;
                //printf("%d %d %d\n",enn,enx,eny);
            }
        }
    }


    for(int i=0; i<5; i++)
    {
        for(int j=0; j<5; j++)
        {
            if(map[n-1][i][j]=='a')
            {
                stn=n-1;
                stx=i;
                sty=j;
                //printf("%d %d %d\n",stn,stx,sty);
            }
        }
    }

    queue<node>q;

    A.n=stn;
    A.x=stx;
    A.y=sty;
    A.step=0;

    visited[A.n][A.x][A.y]=1;
    q.push(A);

    while(!q.empty())
    {
        node u=q.front();
        q.pop();

        if(u.x==enx&&u.y==eny&&u.n==enn)
        {
            printf("%d\n",u.step);
            return;
        }

        node v;

        for(int i=0; i<4; i++)
        {
            v.x=u.x+dir[i][0];
            v.y=u.y+dir[i][1];
            v.n=u.n;
            if(v.n<0||v.x<0||v.x>=5||v.y<0||v.y>=5||visited[v.n][v.x][v.y]==1||map[v.n][v.x][v.y]=='#')
                continue;

            v.step=u.step+1;
            visited[v.n][v.x][v.y]=1;

            if(map[v.n][v.x][v.y]=='@')
            {

                v.n=u.n-1;
                v.step++;
                visited[v.n][v.x][v.y]=1;

            }

            q.push(v);
        }
    }

    return 0;
}

bfs大致思路:

  1. 找到起始点与终点
  2. 标记起始点,起始点入队
  3. 判断队列是否为空,循环每个节点的子节点
  4. 更新队列的队首
  5. 判断是否到达终点
  6. 依次循环每个方向的点,是否超边界范围
  7. 更新步数,标记节点

猜你喜欢

转载自blog.csdn.net/hou_shiyu/article/details/84428951