zoukankan      html  css  js  c++  java
  • POJ3083 Children of the Candy Corn(搜索)

    题目链接

    题意:

    先沿着左边的墙从 S 一直走,求到达 E 的步数。

    再沿着右边的墙从 S 一直走,求到达 E 的步数。

    最后求最短路。

    分析:

    最短路好办,关键是沿着墙走不太好想。

    但只要弄懂如何转,这题就容易了。

    单就沿着左走看一下:

    当前方向     检索顺序

         ↑ :      ← ↑ → ↓

        → :        ↑ → ↓ ← 

         ↓ :      → ↓ ← ↑ 

        ← :        ↓ ← ↑ → 

    如此,规律很明显,假设数组存放方向为 ← ↑ → ↓, 如果当前方向为 ↑, 就从 ← 开始依次遍历,找到可以走的,如果 ← 可以走,就不用再看 ↑ 了。

    在DFS时,加一个参数,用来保存当前的方向。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <queue>
    
    using namespace std;
    
    const int maxn = 100+10;
    
    int dx[] = {0, -1, 0, 1};
    int dy[] = {-1, 0, 1, 0};
    
    int dl[][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
    int dr[][2] = {{0, 1}, {-1, 0}, {0, -1}, {1, 0}};
    
    int sx, sy, ex, ey, n, m;
    char G[maxn][maxn];
    
    struct Pos {
        int x, y, s;
    };
    
    int dfs(int x, int y, int d, int step, int dir[][2]) {
        for(int i=0; i<4; i++) {
            int j = ((d-1+4)%4+i)%4;
            int nx = x+dir[j][0];
            int ny = y+dir[j][1];
    
            if(nx == ex && ny == ey) return step+1;
            if(nx < 0 || ny < 0 || nx > n || ny > m) continue;
            if(G[nx][ny] == '#') continue;
    
            return dfs(nx, ny, j, step+1, dir);
        }
    }
    
    int BFS(int sx, int sy) {
        bool vis[maxn][maxn];
        memset(vis, false, sizeof(vis));
    
        queue<Pos> Q;
        Q.push((Pos){sx, sy, 1});
        vis[sx][sy] = true;
    
        while(!Q.empty()) {
            Pos p = Q.front(); Q.pop();
    
            if(p.x == ex && p.y == ey) return p.s;
    
            Pos np;
            for(int d=0; d<4; d++) {
                np.x = p.x + dx[d];
                np.y = p.y + dy[d];
                np.s = p.s + 1;
    
                if(np.x < 0 || np.x > n || np.y < 0 || np.y > m) continue;
                if(vis[np.x][np.y]) continue;
    
                if(G[np.x][np.y] != '#') {
                    vis[np.x][np.y] = true;
                    Q.push(np);
                }
            }
        }
    
        return -1;
    }
    
    int main() {
        int T, d1, d2;
        //freopen("my.txt", "r", stdin);
        scanf("%d", &T);
    
        while(T--) {
            scanf("%d%d", &m, &n);
    
            for(int i=0; i<n; i++) {
                scanf("%s", G[i]);
                for(int j=0; j<m; j++) {
                    if(G[i][j] == 'S') { sx = i; sy = j; }
                    else if(G[i][j] == 'E') { ex = i; ey = j; }
                }
            }
    
            if(sx == 0) { d1 = 3; d2 = 3; }
            else if(sx == n-1) { d1 = 1; d2 = 1; }
            else if(sy == 0) { d1 = 2; d2 = 0; }
            else if(sy == m-1) { d1 = 0; d2 = 2; }
    
            printf("%d ", dfs(sx, sy, d1, 1, dl));
            printf("%d ", dfs(sx, sy, d2, 1, dr));
            printf("%d
    ", BFS(sx, sy));
    
        }
    
        return 0;
    }
  • 相关阅读:
    VS中生成时“sgen.exe”已退出,代码为 1解决办法
    配置 influxDB 鉴权及 HTTP API 写数据的方法
    InfluxDB 的UTC时间问题与简单的持续查询语句
    C# 中HttpClient的使用中同步异步问题
    Action<T> Delegate
    Task Class
    .net4.0、.net4.5、.net4.6 三者对系统的要求
    vue 组件动态 循环
    js 取得当天0点 / 23:59:59 时间
    vue中element-ui树形控件自定义节点,注意一下
  • 原文地址:https://www.cnblogs.com/tanhehe/p/3154483.html
Copyright © 2011-2022 走看看