zoukankan      html  css  js  c++  java
  • POJ3083 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;
    }
  • 相关阅读:
    基本操作——word中怎样同一页中放入多张图片
    计算机概念入门(二)
    计算机概念入门(一)
    关于黑苹果系统的耳机声音模糊不清问题
    开源项目
    尚硅谷官网资料导航
    this
    最棒的 JavaScript 学习指南(2018版)(转)
    前端文摘:深入解析浏览器的幕后工作原理(转)
    闭包,模块化
  • 原文地址:https://www.cnblogs.com/Lyush/p/2588940.html
Copyright © 2011-2022 走看看