zoukankan      html  css  js  c++  java
  • POJ 3083 Children of the Candy Corn(DFS + BFS)

    题意:

    求从进入点到出口,分别按靠左边,右边和最短距离到达出口所学要的步数。

    思路:

    坐标问题弄的稀里糊涂的,引用 discuss 里面的思路吧:

    向左:依左上右下的顺序针方向走。根据上一个来的方向判断当前坐标开始走的方向,按顺时针走即可,回溯时经过的格子数也要增加,并且方向要反向
    
    向右:依右上左下的逆时针方向走即可
    
    最短是普通的 BFS  
    #include <iostream>
    #include <algorithm>
    #include <deque>
    using namespace std;
    
    const int MAXN = 50;
    
    struct ST {
        int x, y, step;
        ST(int _x, int _y, int _s) : x(_x), y(_y), step(_s) {}
    };
    
    char grid[MAXN][MAXN];
    bool vis[MAXN][MAXN];
    int dir[4][2] = {{0,-1}, {-1,0}, {0,1}, {1,0}};
    int ans;
    
    bool lhsDfs(int x, int y, int o, int step) {
        if (grid[x][y] == 'E') {
            ans = step; 
            return true;
        }
    
        for (int i = o; i < o + 4; ++i) {
            int newx = x + dir[i%4][0];
            int newy = y + dir[i%4][1];
    
            if (grid[newx][newy] != '#') {
                if (lhsDfs(newx, newy, (i-1+4)%4, step+1))
                    return true;
            }
        }
        return false;
    }
    
    bool rhsDfs(int x, int y, int o, int step) {
        if (grid[x][y] == 'E') {
            ans = step; 
            return true;
        }
    
        for (int i = o + 4; i > o; --i) {
            int newx = x + dir[i%4][0];
            int newy = y + dir[i%4][1];
    
            if (grid[newx][newy] != '#') {
                if (rhsDfs(newx, newy, (i+1)%4, step+1))
                    return true;
            }
        }
        return false;
    }
    
    int bfs(int x, int y) {
        deque<ST> q;
        q.push_back(ST(x, y, 1));
        vis[x][y] = true;
    
        while (!q.empty()) {
            ST s = q.front();
            q.pop_front();
    
            if (grid[s.x][s.y] == 'E') 
                return s.step;
    
            for (int i = 0; i < 4; ++i) {
                int newx = s.x + dir[i][0];
                int newy = s.y + dir[i][1];
    
                if (grid[newx][newy] != '#' && !vis[newx][newy]) {
                    vis[newx][newy] = true;
                    q.push_back(ST(newx, newy, s.step + 1));   
                }
            }
        }
    }
    
    int main()
    {
        int cases;
        scanf("%d", &cases);
    
        while (cases--) {
            int row, col;
            scanf("%d %d", &col, &row);
    
            memset(grid, '#', sizeof(grid));
            for (int i = 1; i <= row; ++i)
                scanf("%s", &grid[i][1]);
    
            int x, y;
            for (int i = 1; i <= row; ++i) 
                for (int j = 1; j <= col; ++j)
                    if (grid[i][j] == 'S') x = i, y = j;
    
            lhsDfs(x, y, 0, 1);
            printf("%d ", ans);
    
            rhsDfs(x, y, 0, 1);
            printf("%d ", ans);
    
            memset(vis, false, sizeof(vis));
            printf("%d\n", bfs(x, y));
        }
        return 0;
    }
  • 相关阅读:
    关于线程池,那些你还不知道的事
    Java发送邮件
    原来实现项目多环境打包部署是如此的简单
    史上最全的maven的pom.xml文件详解
    Linux系统基础知识整理(一)
    计算机启动过程的简单介绍 计算机启动流程 计算机BIOS作用 POST 开机自检 计算机启动顺序 分区表 操作系统启动
    交换机工作原理、MAC地址表、路由器工作原理详解
    $(function(){})和$(document).ready(function(){}) 的区别
    关于RAM与ROM的区别与理解
    CDN的作用与基本过程
  • 原文地址:https://www.cnblogs.com/kedebug/p/2964415.html
Copyright © 2011-2022 走看看