kuangbin带你飞系列----poj2251 Dungeon Master

 

本题题意:给出一个三维迷宫,要求找出从起点到终点的最短路径。

代码如下:

/*

    Title:poj2251

    Author: mtl6906

    时间复杂度:O(R*L*C)

*/
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int MAX = 30;
/*

    定义了一个三维的点结构

*/
struct Node
{
    int x,y,z;
    Node operator+(Node node)
    {
        node.x += x;
        node.y += y;
        node.z += z;
        return node;
    }
};
/*

    迷宫的长,宽,高

*/
int L,R,C;
/*

    存迷宫的地形

*/
char a[MAX+2][MAX+2][MAX+2];
/*

    记录每一格相对起点的最短路径长度

*/
int b[MAX+2][MAX+2][MAX+2];
/*

    队列

*/
queue<Node> q;
/*

    方向向量

*/
Node p[6];
/*

    初始化方向向量

*/
void init()
{
    p[0].x = p[1].x = 0;
    p[0].y = p[1].y = 0;;
    p[0].z = 1;
    p[1].z = -1;
    p[2].y = p[3].y = 0;
    p[2].z = p[3].z = 0;
    p[2].x = 1;
    p[3].x = -1;
    p[4].x = p[5].x = 0;
    p[4].z = p[5].z = 0;
    p[4].y = 1;
    p[5].y = -1;
}
/*

    确定点是否在迷宫内

*/
bool range(Node node)
{
    if(node.x <= C-1&&node.x>=0&&node.y <= R-1 && node.y >= 0 && node.z <= L-1 && node.z >=0)return true;
    return false;
}
/*

    获取某点的地形

*/
char block(Node node)
{
    return a[node.z][node.y][node.x];
}
/*
    
    获取某点相对起点的最短路径

*/
int value(Node node)
{
    return b[node.z][node.y][node.x];
}
/*

    尝试朝6个方向前进,应用了dp

*/
void walk(Node node)
{
    Node t;
    for(int i=0;i<6;i++)
    {
        t = p[i] + node;
        if(range(t) && block(t)!='#')
        {
            if(value(t)==-1)
            {
                q.push(t);
                b[t.z][t.y][t.x] = value(node) + 1;
            }
        }
    }
}
/*

    广度优先搜索

*/
void bfs(Node node)
{
    q.push(node);
    b[node.z][node.y][node.x] = 0;
    while(!q.empty())
    {
        walk(q.front());
        q.pop();
    }
}
int main()
{
    init();
    Node start,end;
    while(scanf("%d%d%d",&L,&R,&C),L||R||C)
    {
/*

    将最短路径初始化为-1,每个地形初始化为0

*/
        memset(b,-1,sizeof(b));
        memset(a,0,sizeof(a));
/*

    输入

*/
        for(int i=0;i<L;i++)
        for(int j=0;j<R;j++)
        scanf("%s",a[i][j]);
/*

    确定起点和终点

*/
        for(int i=0;i<L;i++)
        for(int j=0;j<R;j++)
        for(int k=0;k<C;k++)
        {
            if(a[i][j][k] == 'S')
            {
                start.x = k;
                start.y = j;
                start.z = i;
            }
            else if(a[i][j][k] == 'E')
            {
                end.x = k;
                end.y = j;
                end.z = i;
            }
        }
/*

    搜索并打印结果

*/
        bfs(start);
        if(value(end) == -1)printf("Trapped!\n");
        else printf("Escaped in %d minute(s).\n",value(end));
    }
    return 0;
}

这道题就是一个简单的最短路径搜索,只不过三维的话,方向就从4个变为了6个,最短路径毫无疑问就是bfs了,然后dp优化一下,时间复杂度就比较可观了。

攒板子很重要。。。

posted @ 2017-09-06 19:19  mtl6906  阅读(163)  评论(0编辑  收藏  举报