广度优先搜索(BFS)----------------(TjuOj1140_Dungeon Master)

这次整理了一下广度优先搜索的框架,以后可以拿来直接用了。TjuOj1140是一个三维的迷宫题,在BFS时我增加了一个控制数组,用来对队列的出队进行控制,确保每次出队的结点均为同一步长的结点,个人认为比较适合这种迷宫搜索题。

BFS部分的代码如下:

int BFS ( node S , node T )
{
    int s = 1; //充当指针作用
    memset(n,0,sizeof(n));
    n[s] = 1;  //初始化当前距离为1的点数为1(即原点)
    node now = S;
    visit[now.z][now.y][now.x] = 1;
    node temp;
    queue<node> Q;
    Q.push(now);
    while( !Q.empty() ){
        for(int j = 0; j < n[s] ; j++ ){   //依次弹出所有距离为s的方块,进行四周搜索;
            now = Q.front();
            Q.pop();
            for(int i = 0 ; i < 6 ;i++){   //向6个方向探索是否有通路
                temp.x = now.x + dx[i];
                temp.y = now.y + dy[i];
                temp.z = now.z + dz[i];
                if( visit[temp.z][temp.y][temp.x] == 0 && inmap(temp) ){   //防止越界访问
                    temp.ch = maze[temp.z][temp.y][temp.x];
                    if (temp.ch == "E")
                        return s;
                    if (temp.ch == "."){      //如果探索到通路,将该通路标记为(当前距离+1) ,压入队列;
                        n[s + 1]++;                //(当前距离+1)的方块个数++
                        visit[temp.z][temp.y][temp.x] = 1;
                        Q.push(temp);
                    }
                }
            }
        }
        s++;
    }
    return 0;
}

题目比较好理解,从S出发找E(但不一定有解),原文如下:

You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of unit cubes which may or may not be filled with rock. It takes one minute to move one unit north, south, east, west, up or down. You cannot move diagonally and the maze is surrounded by solid rock on all sides.

Is an escape possible? If yes, how long will it take?

Input Specification

The input file consists of a number of dungeons. Each dungeon description starts with a line containing three integers LR and C (all limited to 30 in size). 
L is the number of levels making up the dungeon. 
R and C are the number of rows and columns making up the plan of each level. 
Then there will follow L blocks of R lines each containing C characters. Each character describes one cell of the dungeon. A cell full of rock is indicated by a ‘#‘ and empty cells are represented by a ‘.‘. Your starting position is indicated by ‘S‘ and the exit by the letter ‘E‘. There‘s a single blank line after each level. Input is terminated by three zeroes for LR and C.

Output Specification

Each maze generates one line of output. If it is possible to reach the exit, print a line of the form

Escaped in x minute(s).

where x is replaced by the shortest time it takes to escape. 
If it is not possible to escape, print the line

Trapped!

Sample Input

3 4 5
S....
.###.
.##..
###.#

#####
#####
##.##
##...

#####
#####
#.###
####E

1 3 3
S##
#E#
###

0 0 0

Sample Output

Escaped in 11 minute(s).
Trapped!
/*
 * 1140_Dungeon Master.cpp
 *
 *  Created on: 2018年11月14日
 *      Author: Jeason
 */

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <sstream>
#include <queue>
#define N 70
using namespace std;
int levels,rows,columns;
char maze[N][N][N];
int visit[N][N][N];
int n[ 100000 ] = {0};      //用于记录每个距离的方块个数;
string line;
int dx[6] = {1,-1,0,0,0,0};
int dy[6] = {0,0,1,-1,0,0};
int dz[6] = {0,0,0,0,1,-1};

struct node {
    int x,y,z;
    string ch;
};

bool inmap(node A) {
    if(A.x < 0 || A.x >= columns) return false;
    if(A.y < 0 || A.y >= rows) return false;
    if(A.z < 0 || A.z >= levels) return false;
    return true;
}

int BFS(node S,node T)
{
    int s = 1; //充当指针作用
    memset(n,0,sizeof(n));
    n[s] = 1;  //初始化当前距离为1的点数为1(即原点)
    node now = S;
    visit[now.z][now.y][now.x] = 1;
    node temp;
    queue<node> Q;
    Q.push(now);
    while( !Q.empty() ){
        for(int j = 0; j < n[s] ; j++ ){          //依次弹出所有距离为s的方块,进行四周搜索;
            now = Q.front();
            Q.pop();
            for(int i = 0 ; i < 6 ;i++){   //向6个方向探索是否有通路
                temp.x = now.x + dx[i];
                temp.y = now.y + dy[i];
                temp.z = now.z + dz[i];
                if( visit[temp.z][temp.y][temp.x] == 0 && inmap(temp) ){   //防止越界访问
                    temp.ch = maze[temp.z][temp.y][temp.x];
                    if (temp.ch == "E")
                        return s;
                    if (temp.ch == "."){      //如果探索到通路,将该通路标记为(当前距离+1) ,压入队列;
                        n[s + 1]++;                //(当前距离+1)的方块个数++
                        visit[temp.z][temp.y][temp.x] = 1;
                        Q.push(temp);
                    }
                }
            }
        }
        s++;
    }
    return 0;
}

int main()
{
    node S,T;
    cin >> levels >> rows >> columns;

    while( (levels != 0)&&(rows != 0)&&(columns != 0) ){
        memset(maze, 0, sizeof(maze));          //读入数据;
        memset(visit, 0, sizeof(visit));
        for(int i = 0;i < levels ;i++){
            for(int j = 0;j < rows ;j++){
                cin >> line;
                for(int k = 0;k < columns ;k++){
                    maze[i][j][k] = line[k];
                    if(line[k] == ‘S‘){         //找起点
                        S.z = i; S.x = k; S.y = j;
                        S.ch = "S";
                    }
                }
            }
        }
        int minutes = BFS( S, T );
        if(minutes != 0)
            cout << "Escaped in "<< minutes << " minute(s)."<< endl;
        else
            cout << "Trapped!" <<endl;
//        for(int i = 0;i < levels ;i++){      //输出地图
//            for(int j = 0;j < rows ;j++){
//                for(int k = 0;k < columns ;k++){
//                    cout << maze[i][j][k];
//                }
//                cout << endl;
//            }
//            cout << endl;
//        }
        cin >> levels >> rows >> columns;
    }

    return 0;
}

/*

Sample Input
3 4 5
S....
.###.
.##..
###.#

#####
#####
##.##
##...

#####
#####
#.###
####E

1 3 3
S##
#E#
###

0 0 0
Sample Output
Escaped in 11 minute(s).
Trapped!
*/

原文地址:https://www.cnblogs.com/JeasonIsCoding/p/10013187.html

时间: 2024-11-09 04:41:33

广度优先搜索(BFS)----------------(TjuOj1140_Dungeon Master)的相关文章

广度优先搜索(BFS)

广度优先 Description: 阿狸被困在迷宫,snoopy要去救他,snoopy可以向上.下.左.右四个方向行走,每走一步(格)就要喝掉一瓶益力多.现在给它一个迷宫地图请问:snoopy最少需要多少瓶益力多才能走出迷宫? Input: 先输入一个数t,表示测试的数据个数, 下面输入的就是t个迷宫, 每个迷宫的输入都应包含以下数据, 输入迷宫的大小 n(n<=15),表示迷宫大小为n*n. 再输入迷宫, 用大写字母“S”表示snoopy的位置, 用小写字母“E”表示阿狸被困的位置, 用“.”

【算法导论】--C++实现广度优先搜索bfs

一.题目 根据上次随机生成的100个顶点的无向图和有向图,对其进行广度优先搜索. 二.理解广度优先搜索 广度优先搜索可以将其想象成水滴落入水面溅起了的一圈一圈的涟漪,是由一个起始点开始一圈一圈进行扩散搜索的. [课上老师是这样说的,大家想象一下,发现其实非常形象] 广度优先搜索总是从一个起始点出发,首先扩散这个点周围所有的邻居,然后邻居在去扩散邻居的邻居(*^-^*)...然后一直到最后将整张图都扩散完. 三.代码实现 对于第一次随机生成100个顶点的图进行了细节的修改,将每个顶点的类型改为了自

深度优先搜索DFS和广度优先搜索BFS

DFS简介 深度优先搜索,从起点开始按照某个原则一直往深处走,直到找到解,或者走不下去,走不下去则回溯到前一节点选择另一条路径走,直到找到解为止. BFS简介 广度优先搜索,从起点开始先搜索其相邻的节点,由此向外不断扩散,直到找到解为止. 举例解释 从1开始去寻找5 DFS: 原则:优先选择左手边 过程:1-2-3-4-6-4-5 BFS: 队列情况:1 2.5     5.3 5出来则找到 遍历图中所有点 DFS: 原则:优先选择左手边 过程:1-2-3-4-6-4-5 BFS: 队列情况:1

算法与数据结构基础 - 广度优先搜索(BFS)

BFS基础 广度优先搜索(Breadth First Search)用于按离始节点距离.由近到远渐次访问图的节点,可视化BFS 通常使用队列(queue)结构模拟BFS过程,关于queue见:算法与数据结构基础 - 队列(Queue) 最直观的BFS应用是图和树的遍历,其中图常用邻接表或矩阵表示,例如 LeetCode题目 690. Employee Importance: // LeetCode 690. Employee Importance/* class Employee { publi

广度优先搜索BFS

广度优先搜索可以形成一个广度优先搜索树 算法时间为O(V+E),两重循环 输入:图g,起点start(int) 需要的数据结构:队列Q.color数组(存放每个顶点的颜色) 算法过程: 1. 预处理:1)color数组的每个值都赋为white(表示没被访问过):2)队列Q为空队列 2. 处理起点: 1)color[start]=gray,gray表示顶点已被访问,但其子节点未被处理(指的是入队列):2)Q.enQueue(start) 3. 循环以下操作,直到Q为空 1)int u=Q.deQu

广度优先搜索bfs C++实现

#include<iostream>  #include<vector>  #include<map>  #include<queue>  #include<set>  using namespace std;    vector<int> bfs(map<int, vector<int> > link, int top)  {      queue<int> qe;  //队列用来记录节点的遍历顺

PAT甲级——1091 Acute Stroke (广度优先搜索BFS)

本文同步发布在CSDN:https://blog.csdn.net/weixin_44385565/article/details/94207638 1091 Acute Stroke (30 分) One important factor to identify acute stroke (急性脑卒中) is the volume of the stroke core. Given the results of image analysis in which the core regions

数据结构之 图论---基于邻接矩阵的广度优先搜索遍历(输出bfs遍历序列)

数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历 Time Limit: 1000MS Memory limit: 65536K 题目描述 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜索(BFS)遍历,输出从某个顶点出发的遍历序列.(同一个结点的同层邻接点,节点编号小的优先遍历) 输入 输入第一行为整数n(0< n <100),表示数据的组数. 对于每组数据,第一行是三个整数k,m,t(0<k<100,0<m<(k-1)*k/2,0< t<k),

GraphMatrix::BFS广度优先搜索

查找某一结点的邻居: virtual int firstNbr(int i) { return nextNbr(i, n); } //首个邻接顶点 virtual int nextNbr(int i, int j) //相对于顶点j的下一邻接顶点 { while ((-1 < j) && (!exists(i, --j))); return j; } //逆向线性试探(改用邻接表可提高效率) 对于图中的所有顶点,对每一个连通区域进行BFS: template <typename

关于宽搜BFS广度优先搜索的那点事

以前一直知道深搜是一个递归栈,广搜是队列,FIFO先进先出LILO后进后出啥的.DFS是以深度作为第一关键词,即当碰到岔道口时总是先选择其中的一条岔路前进,而不管其他岔路,直到碰到死胡同时才返回岔道口并选择其他岔路.接下来将介绍的广度优先搜索(Breadth First Search, BFS)则是以广度为第一关键词,当碰到岔道口时,总是先一次访问从该岔道口能直接到达的所有节结点,然后再按这些结点被访问的顺序去依次访问它们能直接到达的所有结点,以此类推,直到所有结点都被访问为止.这就跟平静的水面