B - Xiper的奇妙历险(2)

B - Xiper的奇妙历险(2)

Time Limit: 3000/1000MS (Java/Others)
题目链接:
http://acm.uestc.edu.cn/#/contest/show/99

题目:

转眼间,已经过了10年。
Xiper 和日天都以优异的成绩,从UESTC毕业了。
毕业之后, Xiper 每天勤奋地写代码。然而不知为何, Xiper 总觉得自己的智商越来越低了。
久而久之, Xiper 对日天产生了怀疑。经过的一番调查, Xiper 发现日天竟然在程序里下毒!
日天面对 Xiper 和前来拘留他的潘警察,假意痛哭流涕,并要求 Xiper 亲手给他带上手铐。
然而就在 Xiper 准备给日天带上手铐时,日天微微一笑,竟从背后掏出了一条咸鱼!
“我不做人啦, Xiper !”
潘警官赶忙掏出光剑,向日天砍去。不料成为咸鱼王的日天已然是刀枪不入,毫发无损。
面对强大的日天, Xiper 丝毫不慌,他示意潘警官在豪宅外守候,自己只身迎战。
Xiper 的智商碾压之下,日天被诱入火海之中。被火焰包围的日天发出一阵阵的惨叫声,怕是药丸。
现在,已经打败了日天的 Xiper 要尽快逃出这间在熊熊燃烧的祖传豪宅。
为了简化问题,我们将房子简化成一个 N 层楼,每层楼对应一个L R 列的网格图,并用不同的字符表示每个格点的状态。

.—— 表示该位置为空。

x—— 表示该位置上有障碍,不能移动。

U—— 表示上楼的楼梯入口。

D—— 表示下楼的楼梯入口。

X—— 表示Xiper现在所在的位置。

Y —— 表示 Xiper 要到达的出口的位置,保证在第一层楼的边界上。
每秒 Xiper 可以向前后左右移动一格,或者从楼梯的入口到对应的出口。 Xiper 不能移动到边界外的地方,也不能移动到障碍上。
保证顶楼没有上楼入口,底层没有下楼入口,每个下楼入口对应的出口只会是上楼入口或者障碍,反之亦然。
一个上楼入口只会对应一个下楼入口,且所在层数相邻,所处的行和列一致,反之亦然。
注意,同一层楼可能存在多个楼梯;当楼梯入口对应的出口被障碍堵住时, Xiper 就无法到达出口的位置了。
现在 Xiper 想知道,他最少要用多少时间能逃出来?

Input
第一行三个数字 N L R(1<=N,L,R<=50) ,表示豪宅的大小。
接下来从第 1 层开始依次输入;对于每一层,用L行个长度为 R 的字符串表示该层的状态。

Output
如果可以到达,输出一个数STEP,表示所需最少的步数。否则输出 1

Sample Input

1 1 2
XY
1
2 2 2
YU
..
XD
xx

Sample Output

3

分析:
题目大概就是有第三维迷宫了,要从X走到Y,如果下楼或上楼的时候遇到障碍则走不到终点。
三维bfs~

代码:

#include<cstdio>
#include<queue>
using namespace std;
int n, l, r;

const int maxn = 51;
struct node
{
    int x, y, z;
};
node make_node(int a, int b, int c)
{
    node tmp;
    tmp.x = a;
    tmp.y = b;
    tmp.z = c;
    return tmp;
}
node st, en;
int dx[4] = { 0, 1, 0, -1 }, dy[4] = { 1, 0, -1, 0 };
int d[maxn][maxn][maxn];
char mp[maxn][maxn][maxn];


void init()
{
    for (int i = 0; i<51; i++)
        for (int j = 0; j<51; j++)
            for (int k = 0; k<51; k++)
                d[i][j][k] = -1;
}

int bfs()///it has begin and end
{
    init();
    queue<node>que;
    que.push(st);
    d[st.z][st.x][st.y] = 0;
    while (!que.empty())
    {
        node p = que.front();
        que.pop();
        if (mp[p.z][p.x][p.y] == 'Y')break;

        for (int i = 0; i<4; i++)
        {
            int nx = p.x + dx[i], ny = p.y + dy[i];
            if (nx >= 0 && nx<l&&ny >= 0 && ny <= r&&d[p.z][nx][ny] == -1 && mp[p.z][nx][ny] != 'x')
            {
                d[p.z][nx][ny] = d[p.z][p.x][p.y] + 1;
                que.push(make_node(nx, ny, p.z));
            }
        }

        if (mp[p.z][p.x][p.y] == 'U'&&p.z + 1<n&&mp[p.z + 1][p.x][p.y] != 'x'&&d[p.z + 1][p.x][p.y] == -1){
            d[p.z + 1][p.x][p.y] = d[p.z][p.x][p.y] + 1;
            que.push(make_node(p.x, p.y, p.z + 1));
        }
        if (mp[p.z][p.x][p.y] == 'D'&&p.z - 1 >= 0 && mp[p.z - 1][p.x][p.y] != 'x'&&d[p.z - 1][p.x][p.y] == -1){
            d[p.z - 1][p.x][p.y] = d[p.z][p.x][p.y] + 1;
            que.push(make_node(p.x, p.y, p.z - 1));
        }

    }
    return d[en.z][en.x][en.y];
}

int main()
{
    while (~scanf("%d%d%d", &n, &l, &r))
    {
        for (int i = 0; i<n; i++)
            for (int j = 0; j<l; j++)
                for (int k = 0; k<r; k++){
                    scanf("%c", &mp[i][j][k]);

                    if (mp[i][j][k] == 'X')
                    {
                        st.z = i; st.x = j; st.y = k;
                    }

                    if (mp[i][j][k] == 'Y')
                    {
                        en.z = i; en.x = j; en.y = k;
                    }

                }

        int ans = bfs();
        printf("%d\n", ans);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值