• hdu 2364 Escape【模拟优先队列】【bfs】


    题目链接:https://vjudge.net/contest/184966#problem/A

    题目大意:

    走迷宫。从某个方向进入某点,优先走左或是右。如果左右都走不通,再考虑向前。绝对不能往后走,即使没走过。

    解题思路:

    重点是定义vis数组,每个点的四个方向都走过,这个点才算vis完了。……不过我还是没想明白,为什么能够想到要这样定义vis数组,应该题目做多了就知道了吧。

    其它要注意的点就是如何实现优先左右转弯的功能。

    #include<stdio.h>
    #include<string.h>
    #include<queue>
    using namespace std;
    #define N 85
    int map[N][N], mmin, flag, n, m, vis[N][N][4];
    char str[N][N];
    typedef struct node {
        int x, y;
        int father;//记录方向 
        int step;//记录步数 
    }node;
    
    int bfs(int x, int y)
    {
        int k[4][2] = { 0,1,-1,0,0,-1,1,0 };
        int nx, ny, xi, yi, x1, y1, x2, y2;
        node nextq, nowq;
        memset(vis, 0, sizeof(vis));//初始化标记数组 
        queue<node>Q;
        flag = 0;//标记是否能够成功到达 
        nowq.father = -1;//起点的方向是-1,区别其它点 
        nowq.x = x;
        nowq.y = y;
        nowq.step = 0;//初始化起点 
        vis[x][y][0] = 1, vis[x][y][1] = 1;//起点标记为已经走过 
        vis[x][y][2] = 1, vis[x][y][3] = 1;
        Q.push(nowq);//将起点加入队列 
        while (!Q.empty())
        {
            nowq = Q.front();
            Q.pop();
            if (nowq.x == 0 || nowq.y == 0 || nowq.x == n - 1 || nowq.y == m - 1)//到达出口,因为map的边界上只有一个为'.',且该点为出口
            {
                if (str[nowq.x][nowq.y] != '#')
                    flag = 1;//能够成功到达 
                return nowq.step;
            }
            for (int i = 0; i < 4; i++)
            {
                nx = nowq.x + k[i][0];
                ny = nowq.y + k[i][1];
                if (nx < 0 || ny < 0 || nx > n - 1 || ny > m - 1 || str[nx][ny] == '#' || vis[nx][ny][i])
                    continue;    //不能越界,不能是墙,不能已经是访问过的点 
                nextq.x = nx;
                nextq.y = ny;
                nextq.father = i;//记录父点到当前点的方向 
                nextq.step = nowq.step + 1;//步数加1 
                if (nowq.father % 2 == i % 2)
                {
                    if (nowq.father == i)
                    {
                        x1 = nowq.x + k[(i + 1) % 4][0];
                        y1 = nowq.y + k[(i + 1) % 4][1];
                        x2 = nowq.x + k[(i - 1 + 4) % 4][0];
                        y2 = nowq.y + k[(i - 1 + 4) % 4][1];
                        if (str[x1][y1] != '.'&&str[x2][y2] != '.')//如果当前位置左右两边都不能走即只能直走 
                        {
                            vis[nx][ny][i] = 1;//标记该方向为已经访问过
                            Q.push(nextq);
                        }
                    }
                }
                else
                {
                    vis[nx][ny][i] = 1;
                    Q.push(nextq);
                }
            }
        }
        return -1;
    }
    int main()
    {
        int t, i, j, x, y;
        scanf("%d", &t);
        while (t--)
        {
            scanf("%d%d", &n, &m);
            memset(str, 0, sizeof(str));
            for (i = 0; i < n; i++)
            {
                scanf("%s", str[i]);
                for (j = 0; j < m; j++)
                {
                    if (str[i][j] == '@')//找到起点,存入x,y. 
                    {
                        x = i;
                        y = j;
                    }
                }
            }
            mmin = bfs(x, y);//返回步数 
            if (flag)//如果能到达出口。输出步数 
                printf("%d
    ", mmin);
            else
                printf("-1
    ");    //否则输出-1 
    
        }
        return 0;
    }                        

    2018-03-25


    作者:is_ok
    出处:http://www.cnblogs.com/00isok/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    洛谷 P1786 帮贡排序 题解
    Bayes++ Library入门学习之熟悉UKF相关类
    Bayes++ Library入门学习之熟悉class-Bayesian_filter_base(2)
    Bayes++ Library入门学习之熟悉class-Importance_resampler
    Bayes++ Library入门学习之熟悉class-Bayesian_filter_base(1)
    Bayes++ Library入门学习之熟悉namespace
    CMake入门之创建一个基于PCL的最小工程
    CUDA学习之从CPU架构说起
    #pragma 预处理指令详解
    C++中inline函数
  • 原文地址:https://www.cnblogs.com/00isok/p/8647087.html
Copyright © 2020-2023  润新知