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;

}

你可能感兴趣的:(children)