POJ2251:Dungeon Master(BFS)

poj这几天挂掉了,我用UVA提交的= =,poj2251 || UVA532。

poj2251:传送门

vjudge打不开用这个:传送门(这个是poj挂在vjudge上的题目,poj挂了这个vjudge也不好使,但是下面这个传送门poj挂了可以继续提交)。

poj挂了可以用这个  :  含有我TLE的UVA传送门

题目

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!

题意:(三维:有长宽高的)

一个3D(三维)监狱,可以往前,后,左,右,上,下,6个方向走从‘S’开始遇到 ’.‘可以走,遇到 ‘#’(墙壁)走不了,直到 ‘E’ 结束,最后输出最少走过的点数。

我起初用深搜(深受其害,大家千万别盲目相信poj题目分类啊)果断TLE,发现以后就是想广搜,看起来没什么陷阱,结果还是哇(WA)了好几发。

陷阱:

0. 由于不习惯使用三维数组,用的a(列数)*b(行数乘以层数)的数组,结果撸完之后发现有一个栗子过不去。

3 3 3
###
#E#
#.#

#..
.##
.#.

...
...
..S

(UVA的uDebug功能还是不错的,不过uDebug过了,不一定能A,数据不全)

 这里走到(3,1)就是第四行第二列的时候直接就走到第三行第二列去了。所以应该加一个判断(代码第一个高亮处),遇到上边缘判断一下不让他往上走,遇到下边缘判断一下不让他往下走,搞定。

            1.代码第二个高亮处不应该放到

if(imap(dx, dy) && (map[dx][dy] == '.' || map[dx][dy] == 'E' ) && !book[dx][dy])

外面。


思路:这道题期初想到深搜,代码就不上了,明明记得提交之后是TLE结果找不到了= =。

想想也是,30*30*30铁定会超时的啊。看了别人的解法都说是广搜,嘛,智障啊,思维不连贯,断断续续写了四天,最终A掉了。

上代码:


#include<stdio.h>
#include<string.h>

int l, r, c;
char map[1000][35];
int book[1000][35];

struct point{
    int x;
    int y;
    int temp;
};
struct point pp[30000];
int dir[4][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
int ans;
int q;
int tmp;
int sx, sy;
int ex, ey;
int imap(int x, int y);
void bfs(int x, int y);
int aa = 0;
int main()
{
    int i, j, k;
    while(scanf("%d %d %d", &l, &r, &c) && (l || r || c))
    {
        memset(book, 0, sizeof(book));
        memset(pp, -1, sizeof(pp));
        ans = 1;
        q = 0;
        tmp = 0;
        getchar();

        for(i = 0; i <  l * r; i++){
            if(i != 0 && i % r == 0)
                getchar();
            for(j = 0; j < c; j++){
                scanf("%c", &map[i][j]);
                if(map[i][j] == 'S'){
                    sx = i;
                    sy = j;
                    book[sx][sy] = 1;
                }
                if(map[i][j] == 'E'){
                    ex = i;
                    ey = j;
                }
            }
            getchar();
        }
//        printf("\n");
        bfs(sx, sy);
        if(tmp == 0)
            printf("Trapped!\n");
    }
    return 0;

}

int imap(int x, int y)
{
    if(x >= 0 && x < r * l && y >= 0 && y < c)
        return 1;
    return 0;
}
void bfs(int x, int y)
{
    int i, dx, dy;
    pp[q].x = x;
    pp[q].y = y;
    pp[q].temp = 0;
    while(ans >= q && pp[q].x != -1){

        x = pp[q].x;
        y = pp[q].y;
        for(i = 0; i < 6; i++){

            if((x + 1) % r == 0 && i == 1)
                continue;
            if(x % r == 0 && i == 0)
                continue;

            if(i >= 0 && i < 4){
                dx = x + dir[i][0];
                dy = y + dir[i][1];
            }
            else if(i == 4){
                dx = x + r;
                dy = y;
            }
            else if(i == 5){
                dx = x - r;
                dy = y;
            }
            if(imap(dx, dy) && (map[dx][dy] == '.' || map[dx][dy] == 'E' ) && !book[dx][dy]){

                    book[dx][dy] = 1;
                    pp[ans].x = dx;
                    pp[ans].y = dy;
                    pp[ans].temp = pp[q].temp + 1;
//                    printf("%d %d %d\n", dx, dy, pp[ans].temp);
                    if(map[pp[ans].x][pp[ans++].y] == 'E'){
                        tmp = 1;
//                        for(i = 1; i < 10; i++)
//                            printf("%d %d %d\n", pp[ans - i].x, pp[ans - i].y, pp[ans - i].temp);
                        printf("Escaped in %d minute(s).\n", pp[ans - 1].temp);
                        return;
                    }
            }
        }
        q++;
    }
}


今天看了一 下     C++的队列  (点击可跳转),  感觉用起来顺手多了,起码写起来感觉很方便。但感觉没有C练脑子。

参考下           大佬的C++写法。(其中不是很理解next = a;这句话,感觉没什么用啊,注释后也A惹= =。)(点击可跳转)

感悟0.切记因为写博客而做无脑劳动!!!

        1.切切实实的思考和进步才重要,注重结果!!!

        2.夜晚写代码因为自己太笨而并非勤奋!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值