深搜和广搜

Dungeon Master

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 58498 Accepted: 21525

Description

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

The input consists of a number of dungeons. Each dungeon description starts with a line containing three integers L, R 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 L, R and C.

Output

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!

Source

Ulm Local 1997

深搜只是确定它是否存在;(深搜时间复杂度远远大于广搜,所以一般找到结果之后都会选择直接退出)

广搜才是确定它的最短路径;

#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int vis[36][36][36];
int ans;
char tu[36][36][36];
int l,r,c;
int flag;
int cnt;
int zhong;
int movee[19]= {0, 0,1,0, 0,-1,0, 0,0,1, 0,0,-1, 1,0,0, -1,0,0 };
//1 (1)   4(2)     7(3)    10(4)    13(5)    16(6)

void in(int high,int x,int y)
{
    if(tu[high][x][y]=='E' && cnt < zhong)
    {
        zhong=cnt;
        ans=cnt;
        return;
    }
    else
    {
        for(int i=1; i<=16; i=i+3)
        {

            high=high+movee[i];
            x=x+movee[i+1];
            y=y+movee[i+2];

            if( ( tu[high][x][y]=='.' || tu[high][x][y]=='E' ) && vis[high][x][y]==0 && high>=1 && high<=l && x>=1 && x<=r &&y>=1 &&y<=c )
            {

                vis[high][x][y]=1;
                cnt++;

                in(high,x,y);

                cnt--;
                vis[high][x][y]=0;
            }
            high=high-movee[i];
            x=x-movee[i+1];
            y=y-movee[i+2];

        }
    }
    return;
}


int main()
{

    while((cin>>l>>r>>c) && l && r &&c)
    {
        memset(vis,0,sizeof(vis));
        cnt=0;
        int high,x,y;
        int high_end,x_end,y_end;
        ans=0;
        zhong=0x3f3f3f;

        for(int i=1; i<=l; i++)
        {
            for(int j=1; j<=r; j++)
            {
                for(int k=1; k<=c; k++)
                {
                    cin>>tu[i][j][k];

                    if( tu[i][j][k]=='S' )
                    {
                        high=i;
                        x=j;
                        y=k;
                        //cout<<i<<j<<k<<endl;
                    }
                    if( tu[i][j][k]=='E' )
                    {
                        high_end=i;
                        x_end=j;
                        y_end=k;
                    }
                }

            }

        }
        vis[high][x][y]=1;
        in(high,x,y);
        if(ans)
        {
           printf("Escaped in %d minute(s).\n",ans);
        }
        else
        {
           printf("Trapped!\n");
        }


    }


}

 

#include<stdio.h>
#include<iostream>
#include<queue>
#include<string.h>
using namespace std;
char map[30][30][30];        //记录节点信息
int vis[30][30][30];        //标记是否访问

int base[6][3] = { {-1,0,0},{1,0,0},{0,-1,0},{0,1,0},{0,0,-1},{0,0,1} };

int L, R, C;

typedef struct
{
    int x, y, z;            //位置坐标
    int step;                //出发点到该点的步数
} node;

node s;                //起点
node e;                //终点
node curp;             //跳出循环时的节点


bool success(node cur)
{
    if (cur.x == e.x  &&  cur.y == e.y && cur.z == e.z)
        return true;
    else
        return false;
}


bool check(int x, int y, int z)
{
    if ( (x >= 0) && (x < L) && (y >= 0) && (y < R) && (z >= 0) && (z < C) && (!vis[x][y][z]) && (map[x][y][z] == '.' || map[x][y][z] == 'E'))
        return true;
    else
        return false;
}


void bfs()
{

    queue<node> q;
    q.push(s);

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

        if ( success(curp) )
            return;

        else
        {
            vis[curp.x][curp.y][curp.z] = 1;

            node next;
            for (int i = 0; i < 6; i++)
            {
                next.x = curp.x + base[i][0];
                next.y = curp.y + base[i][1];
                next.z = curp.z + base[i][2];

                if ( check(next.x, next.y, next.z) )        //扩展队列
                {
                    next.step = curp.step + 1;
                    vis[next.x][next.y][next.z] = 1;

                    q.push(next);

                }
            }
        }
    }
}
int main()
{
    while (scanf("%d%d%d", &L, &R, &C))
    {
        if((L == 0) && (R == 0) && (C == 0))
            break;

        memset(vis, 0, sizeof(vis));

        for (int i = 0; i < L; i++)
        {
            for (int j = 0; j < R; j++)
            {
                for (int k = 0; k < C; k++)
                {
                    cin>>map[i][j][k];
                    if (map[i][j][k] == 'S')
                    {
                        s.x = i;
                        s.y = j;
                        s.z = k;
                        s.step = 0;
                    }
                    else if (map[i][j][k] == 'E')
                    {
                        e.x = i;
                        e.y = j;
                        e.z = k;
                    }
                }

            }
        }

        bfs();
        if ( curp.x == e.x && curp.y == e.y && curp.z == e.z )
            printf("Escaped in %d minute(s).\n", curp.step);
        else
            printf("Trapped!\n");
    }
    return 0;
}

 

图的度优先索(Depth First Search, DFS)广度优先索(Breadth First Search, BFS)是图的两种重要遍历方式。 度优先索(DFS)假设初始状态是图中所有顶点均未被访问,从某个顶点v出发,首先访问该顶点,然后依次从它的各个未被访问的邻接点出发度优先索遍历图,直至图中所有v有路径相通的顶点都被访问到。若此时尚有其他顶点未被访问到,则另选一个未被访问的顶点作为起始点,重复上述过程,直至图中所有顶点都被访问到。其实现可以采用邻接矩阵或邻接表来表示图进行遍历,还能对非连通图进行度优先遍历,并且有相应的算法分析 [^3]。 广度优先索(BFS)需要借助队列来遍历。首先,选取图中某一顶点vi作为出发点,访问后将其入队并标记为已访问(使用队列用于避免重复访问,存放已经访问过的各邻接顶点);接着依次访问与vi邻接的顶点,即当队列不为空时检查出队顶点的所有邻接顶点,访问未被访问的邻接顶点并将其入队,重复该过程;可概括为由起始顶点开始,按照广度优先的顺序逐层遍历与当前顶点相邻的顶点将其访问;当队列为空时跳出循环,即所有已被访问的顶点的邻接顶点均被访问到,则此时遍历完成 [^4]。 值得注意的是,广度优先索在某些情况下可能不是最优的,例如当图很大或者结构复杂时,它可能需要遍历很多节点才能找到目标节点,在这种情况下,可能需要考虑使用其他索算法,如度优先索(DFS)或启发式索算法等 [^2]。 以下是简单的Python代码示例来实现DFSBFS: ```python # 图的邻接表表示 graph = { 'A': ['B', 'C'], 'B': ['A', 'D', 'E'], 'C': ['A', 'F'], 'D': ['B'], 'E': ['B', 'F'], 'F': ['C', 'E'] } # 度优先索 def dfs(graph, start, visited=None): if visited is None: visited = set() if start not in visited: print(start, end=' ') visited.add(start) for neighbor in graph[start]: dfs(graph, neighbor, visited) # 广度优先索 from collections import deque def bfs(graph, start): visited = set() queue = deque([start]) visited.add(start) while queue: vertex = queue.popleft() print(vertex, end=' ') for neighbor in graph[vertex]: if neighbor not in visited: queue.append(neighbor) visited.add(neighbor) # 测试 print("DFS:") dfs(graph, 'A') print("\nBFS:") bfs(graph, 'A') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值