zoukankan      html  css  js  c++  java
  • 01矩阵-【BFS】

    01矩阵

    给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。两个相邻元素间的距离为 1 ,方格斜方向不计算距离。

    示例 1:
    输入:

    [0 0 0
    0 1 0
    0 0 0]
    

    输出:

    [0 0 0
    0 1 0
    0 0 0]
    

    示例 2:
    输入:

    [0 0 0
    0 1 0
    1 1 1]
    

    输出:

    [0 0 0
    0 1 0
    1 2 1]
    

    注意:

    给定矩阵的元素个数不超过 10000。
    给定矩阵中至少有一个元素是 0。
    矩阵中的元素只在四个方向上相邻: 上、下、左、右。

    思路:

    对每个值为0的点进行bfs,不断更新最短路径,因为元素个数不超过10000所以最长距离也就是199,先把res[][]数组的值设置成205即可,

    记得要加标记数组,防止重复访问,会陷入死循环,我第一次就是忘记加了。 对0进行bfs搜索要比对1进行bfs搜索要好,因为前者更方便剪枝。

    #include <iostream>
    #include <math.h>
    #include <queue>
    #include <string.h>
    using namespace std;
    
    // 方向数组 上右下左
    int dx[4] = {-1, 0, 1, 0};
    int dy[4] = {0, 1, 0, -1};
    // 地图
    int nums[105][105];
    // 是否访问过   0代表没访问过,1代表访问过
    int vis[105][105];
    // 结果
    int res[105][105];
    // 地图长度
    int n;
    
    bool check(int x, int y)
    {
        // 判断在界内,并且没被访问过,并且值为1。(值为0的话,肯定是从0这个点向其他点扩展,比原先的点更近一点)
        return x >= 0 && y >= 0 && x < n && y < n && vis[x][y] == 0 && nums[x][y] == 1;
    }
    
    void bfs(int x, int y)
    {
        res[x][y] = 0;
        queue<pair<int, int>> q;
        memset(vis, 0, sizeof(vis));
        vis[x][y] = 1; //设置(x,y)访问过
        q.push({x, y});
    
        while (!q.empty())
        {
            // len++;
            pair<int, int> t = q.front();
            q.pop();
            for (int i = 0; i < 4; i++)
            {
                int newx = t.first + dx[i];
                int newy = t.second + dy[i];
                if (check(newx, newy))
                {
                    // 将新点标记访问过
                    vis[newx][newy] = 1;
                    // 上一个点的长度+1,便是bfs层数。    刷新最短距离。
                    res[newx][newy] = min(res[t.first][t.second] + 1, res[newx][newy]);
                    q.push({newx, newy});
                }
            }
        }
    }
    
    int main()
    {
        cin >> n;
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                cin >> nums[i][j];
    
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                res[i][j] = 205;
    
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                if (nums[i][j] == 0)
                    bfs(i, j);
    
        cout << endl;
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
                cout << res[i][j] << " ";
            cout << endl;
        }
    
        return 0;
    }
    
  • 相关阅读:
    公用表表达式(CTE)的递归调用
    c# 如何让tooltip显示文字换行
    实战 SQL Server 2008 数据库误删除数据的恢复
    SQL SERVER数据库中 是否可以对视图进行修改删除
    asp.net中实现文件批量上传
    sql server 2008学习2 文件和文件组
    sql server 2008学习3 表组织和索引组织
    sql server 2008学习4 设计索引的建议
    sql server 2008学习10 存储过程
    .net 调用 sql server 自定义函数,并输出返回值
  • 原文地址:https://www.cnblogs.com/52dxer/p/12843026.html
Copyright © 2011-2022 走看看