zoukankan      html  css  js  c++  java
  • HDU 1728 逃离迷宫(拐弯问题,对BFS最优解的新理解)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1728

    题意:'.'可以走,'*'障碍,给你起点终点,问从起点最多拐k次弯,问能不能到终点。。

    开始做的时候,以为,用优先队列拐弯数小的优先,然后每次用队头遍历旁边的4个点。。。。结果WA了。。。而且还用东西来处理是否拐弯。。。

    用BFS来处理最优解问题要用队头来遍历完所有最优解并且进队,再重复。。。而上面WA的原因是,我只把相邻的4个点进了队,而在同行,同列还有最优解没进队,导致那些之前没进队的,进队的时候就已经不是最优解了。。。。

    这题要用队头遍历4个方向(而不是4个点)。。。每步都是最优,所以最后也是最优。。。。

    vis[][]是该点有没遍历过,遍历过的就已经最优了。。。即,队列里的都已经最优了,也就是队头也是最优的。。。。

    要特别注意代码标成//********的地方

    对比正确和错误代码的图:

    错误代码是while(里有!vis[][])而下面没有vis[][];

    但是,如果左边那竖的二变成三的时候,那3个'.'就每人遍历了,所以代码是队头遍历同行同列中不出界且!='*'的

    点,跳过标记过的(已经最优了),将未标记的点入队。。。

    还有我的q1.turn_num = -1初始化为-1(为了把起点同行同列拐弯数是0,所以如果题目起点等于终点的话,最少拐弯数就成了-1)。。。。其实如果题目改成求最少拐弯数的话,就稍微判断一下是不是起点等于终点。。。。

    代码:

    #include <iostream>
    #include <queue>
    using namespace std;
    
    const int M = 111;
    
    int n, m;
    int max_turn;
    int star_x, star_y, end_x, end_y;
    char g[M][M];
    bool vis[M][M];
    int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
    //右,下,左,上
    
    
    struct Node
    {
        int x, y;
        int turn_num;
    
    };
    
    int Bfs()
    {
        queue <Node> q;
        Node q1;
        q1.x = star_x;
        q1.y = star_y;
        q1.turn_num = -1;
        q.push(q1);
        vis[star_x][star_y] = 1;
    
        while (!q.empty())
        {
            Node q2 = q.front();
            q.pop();
    
            if (q2.x == end_x && q2.y == end_y && q2.turn_num <= max_turn)
            {
                return 1;
            }
    
            q1.turn_num = q2.turn_num + 1;
            
            for (int i = 0; i < 4; i++)
            {
                q1.x = q2.x + dir[i][0];
                q1.y = q2.y + dir[i][1];
                while (q1.x >= 1 && q1.x <= n && q1.y >= 1 && q1.y <= m && g[q1.x][q1.y] == '.'/* && !vis[q1.x][q1.y]*/)//**********
                {
                    if (!vis[q1.x][q1.y])//*********************************
                    {
                    q.push(q1);
                    vis[q1.x][q1.y] = 1;
                    }
                    q1.x += dir[i][0];
                    q1.y += dir[i][1];
                }
            }
        
        }
        return 0;
    }
    
    int main()
    {
        int t;
        scanf("%d", &t);
        while (t--)
        {
            scanf("%d%d", &n, &m);
            for (int i = 1; i <= n; i++)
            {
                for (int j = 1; j <= m; j++)
                {
                    scanf(" %c", &g[i][j]);
                }
            }
    
            scanf("%d%d%d%d%d", &max_turn, &star_y, &star_x, &end_y, &end_x);
    
            memset(vis, 0, sizeof(vis));
    
    
    
            if (Bfs())
            {
                puts("yes");
            }
            else
            {
                puts("no");
            }
        }
        return 0;
    }
  • 相关阅读:
    由于服务主机:DCOM服务进程占用过多CPU,导致系统卡死
    MySQL优化
    input type="file"文件上传到后台读取
    mysql 创建事件
    Quartz.Net实现的定时执行任务调度
    js 编码详解
    C# DateTime.Now 详解
    C# 读写text 详细讲解
    百度地图API详细介绍
    layui table 详细讲解
  • 原文地址:https://www.cnblogs.com/qiufeihai/p/2659159.html
Copyright © 2011-2022 走看看