POJ-3083 Children of the Candy Corn 恶心搜索

  之前有听说如果在一个迷宫中一直沿着某一堵墙走的话,那么一定可以走出这个迷宫,这题讲的就是这个内容。这题的问法比较奇怪,问你沿着左边的墙,右边的墙走所花的时间和最少所花的时间。该题难点就在与如何让dfs的时候能够沿着墙走。其实是有规律的,那就是往左边走是顺时针方向dfs,往右走逆时针方向走dfs,每次要确定上一次来的方向,这样能够确定你第一次试探的方向是那个方向。例如:如果从最左边的墙进入的话,那么首先选择往上走,否则向前走,再否则向下走,最后还是没法走的话就向左走(往回走),走了之后就直接return,每次走了之后绝对不会再换方向搜索。这题竟然错在了手写的找最短路的队列上。

代码如下:

#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
using namespace std;

int N, M, sx, sy, visit[45][45];

int llen, rlen, slen, front, tail, dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};

int ldir[4][2] = {-1, 0, 0, 1, 1, 0, 0, -1};
int rdir[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};
int linitdir, rinitdir;

char G[45][45];

struct Node
{
    int x, y, s;
}e[1000000], pos;

bool judge(int x, int y)
{
    if (x < 1 || x > N || y < 1 || y > M) {
        return false;
    }
    return true;
}

int bfs()
{
    int xx, yy;
    front = 0;
    tail = 1;
    e[tail].x = sx, e[tail].y = sy;
    e[tail].s = 1;
    while (front != tail) {
        pos = e[++front];
        for (int i = 0; i < 4; ++i) {
            xx = pos.x + dir[i][0], yy = pos.y + dir[i][1];
            if (!visit[xx][yy] && judge(xx, yy)) {
                visit[xx][yy] = 1;
                if (G[xx][yy] == '.') {
                    ++tail;
                    e[tail].x = xx, e[tail].y = yy;
                    e[tail].s = pos.s + 1;
                }
                else if (G[xx][yy] == 'E') {
                    return pos.s + 1;
                }
            }
        }
    }
}

void getinitdir()
{ 
    if (sy == 1) {
        linitdir = 0;
        rinitdir = 0;
    }
    else if (sx == 1) {
        linitdir = 1;
        rinitdir = 3;
    }
    else if (sy == M) {
        linitdir = 2;
        rinitdir = 2;
    }
    else {
        linitdir = 3;
        rinitdir = 1;
    }
}

int getslen()
{
    memset(visit, 0, sizeof (visit));
    visit[sx][sy] = 1;
    return bfs();
}

int ldfs(int x, int y, int dd, int step)
{
    for (int i = dd, j = 0; j < 4; ++i, ++j) {
        int k = i % 4;
        int xx = x + ldir[k][0], yy = y + ldir[k][1];
        if (judge(xx, yy) && G[xx][yy] != '#') {
            if (G[xx][yy] == 'E') {
                return step + 1;
            }
            else if (G[xx][yy] == '.') {
                if (xx == x) {
                    if (yy == y + 1) {
                        k = 0;
                    }
                    else {
                        k = 2;
                    }
                }
                else {
                    if (xx == x + 1) {
                        k = 1;
                    }
                    else {
                        k = 3;
                    }
                }
                return ldfs(xx, yy, k, step+1);
            }
        }
    }
}

int rdfs(int x, int y, int dd, int step)
{
    for (int i = dd, j = 0; j < 4; ++i, ++j) {
        int k = i % 4;
        int xx = x + rdir[k][0], yy = y + rdir[k][1];
        if (judge(xx, yy) && G[xx][yy] != '#') {
            if (G[xx][yy] == 'E') {
                return step + 1;
            }
            else if (G[xx][yy] == '.') {
                if (xx == x) {
                    if (yy == y + 1) {
                        k = 0;
                    }
                    else {
                        k = 2;
                    }
                }
                else {
                    if (xx == x+ 1) {
                        k = 3;
                    }
                    else {
                        k = 1;
                    }
                }
                return rdfs(xx, yy, k, step+1);
            }
        }
    }
}

int main()
{
    int T, flag;
    scanf("%d", &T);
    while (T--) {
        flag = 0;
        scanf("%d %d", &M, &N);
        for (int i = 1; i <= N; ++i) {
            scanf("%s", G[i]+1);
            for (int j = 1; !flag && j <= M; ++j) {
                if (G[i][j] == 'S') {
                    sx = i, sy = j;
                    flag = 1;
                }
            }
        }
        getinitdir();
        slen = getslen();
        llen = ldfs(sx, sy, linitdir, 1);
        rlen = rdfs(sx, sy, rinitdir, 1);
        printf("%d %d %d\n", llen, rlen, slen);
    }
    return 0;
}
posted @ 2012-07-12 23:53  沐阳  阅读(577)  评论(0编辑  收藏  举报