首页 > 其他分享 >矩阵距离——广度优先搜索

矩阵距离——广度优先搜索

时间:2024-07-20 09:25:50浏览次数:16  
标签:优先 int mn 矩阵 vis && 广度 include dis

题目描述

给定一个N行M列的01矩阵 A,A[i][j] 与 A[k][l] 之间的曼哈顿距离定义为:

dist(A[i][j],A[k][l])=|i-k|+|j-l|

输出一个N行M列的整数矩阵B,其中:

B[i][j]=min(1≤x≤N,1≤y≤M,A[x][y]=1)⁡{dist(A[i][j],A[x][y])}

即求与每个位置曼哈顿距离最近的1

N,M≤1000。

输入格式

第一行两个整数n,m。

接下来一个N行M列的01矩阵,数字之间没有空格。

输出格式

一个N行M列的矩阵B,相邻两个整数之间用一个空格隔开。

输入输出样例

输入样例1:复制

3 4
0001
0011
0110

输出样例1:复制

3 2 1 0 
2 1 0 0 
1 0 0 1

【耗时限制】2000ms 【内存限制】128MB


这道题如果一个一个枚举,就会超时,要mn个bfs,时间复杂度O(mn*mn)

就像这样,全TLE,0分

#include <iostream>
#include <cstdio>
#include <cstring>
#include <sstream>
#include <algorithm>
#include <string>
#include <queue>
using namespace std;
const int N=1e3+5;
int n,m;
int vis[N][N],a[N][N],dis[N][N];
int dx[4]={0,0,-1,1},dy[4]={1,-1,0,0};
struct node{
    int x,y;
};
int bfs(int x,int y){
    memset(vis,0,sizeof(vis));
    memset(dis,0,sizeof(dis));
    queue<node> q;
    q.push((node){x,y});
    if(a[x][y]==1) return 0;
    vis[x][y]=1;
    dis[x][y]=0;
    while(!q.empty()){
        node f=q.front();q.pop();
        for(int i=0;i<4;i++){
            int u=f.x+dx[i],v=f.y+dy[i];
            if(u>=1&&u<=n&&v>=1&&v<=m&&!vis[u][v]){
                dis[u][v]=dis[f.x][f.y]+1;
                if(a[u][v]) return dis[u][v];
                q.push((node){u,v});
            }
        }
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        string s;
        cin>>s;
        for(int j=1;j<=m;j++){
            a[i][j]=s[j-1]-'0';
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cout<<bfs(i,j)<<" ";
        }
        cout<<endl;
    }
    return 0;
}

应该所有1都入队列,只用一个bfs,时间复杂度O(mn)

这是正确的代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <sstream>
#include <algorithm>
#include <string>
#include <queue>
using namespace std;
const int N=1e3+5;
int n,m;
int vis[N][N],a[N][N],dis[N][N];
int dx[4]={0,0,-1,1},dy[4]={1,-1,0,0};
struct node{
    int x,y;
};
void bfs(){
    memset(vis,0,sizeof(vis));
    queue<node> q;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(a[i][j]==1){
                q.push((node){i,j});
                vis[i][j]=1;
            }
        }
    }
    while(!q.empty()){
        node f=q.front();q.pop();
        for(int i=0;i<4;i++){
            int u=f.x+dx[i],v=f.y+dy[i];
            if(u>=1&&u<=n&&v>=1&&v<=m&&!vis[u][v]){
                dis[u][v]=dis[f.x][f.y]+1;
                vis[u][v]=1;
                q.push((node){u,v});
            }
        }
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        string s;
        cin>>s;
        for(int j=1;j<=m;j++){
            a[i][j]=s[j-1]-'0';
        }
    }
    bfs();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cout<<dis[i][j]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

标签:优先,int,mn,矩阵,vis,&&,广度,include,dis
From: https://blog.csdn.net/m0_73926005/article/details/140565698

相关文章

  • [C++]优先级队列
    1.了解优先级队列优先级队列是一种容器适配器,根据一些严格的弱排序标准,专门设计使其第一个元素始终是它所包含的元素中最大的元素。此上下文类似于堆,其中可以随时插入元素,并且只能检索最大堆元素(优先级队列中顶部的元素)。优先级队列是作为容器适配器实现的,容器适配器是使......
  • 螺旋数字矩阵
    题目描述疫情期间,小明隔离在家,百无聊赖,在纸上写数字玩。他发明了一种写法:给出数字个数n(0<n≤999)和行数m(0<m≤999),从左上角的1开始,按照顺时针螺旋向内写方式,依次写出2,3,....,n,最终形成一个m行矩阵。小明对这个矩阵有些要求:每行数字的个数一样多列的数量尽可......
  • 线程组和线程优先级
    线程组每个Thread必然存在于一个ThreadGroup中,Thread不能独立于ThreadGroup存在。执行main()方法的线程名字是main,如果在newThread时没有显式指定,那么默认将父线程的线程组设置为自己的线程组。publicstaticvoidmain(String[]args){Threadthread=newT......
  • 代码随想录算法训练营第二天| 977 有序数组平方 209 长度最小子数组 59 螺旋矩阵
    977有序数组平方funcsortedSquares(nums[]int)[]int{ //思路,最简单,先平方,再排序 foridx,num:=rangenums{ nums[idx]=num*num } //插排思想,维护两个列表,将无序列表元素插入到有序列表合适位置 fori:=1;i<len(nums);i++{//此处nums[:i]即我们维......
  • 代码随想录算法训练营第42期 第二天 | LeetCode977. 有序数组的平方、209. 长度最小的
    一、977.有序数组的平方学习链接:有序数组的平方状态:暴力解法与双指针都做出来了时间复杂度:暴力解法O()    双指针解法 O()细节之处:暴力解法1       双指针解法1  暴力解法classSolution{publicint[]sortedSquares(int[]nums){......
  • 矩阵向量点积、Batch(批)理解、one-hot编码
    矩阵向量点积output=relu(dot(W,input)+b)input的每个元素为三维的特征向量的特征,W矩阵:行:存储节点权重数组列数表示节点数量所以result[1]和result[0]运算互不干扰,能够并行加速上述数学角度运算代码如下:defnaive_matrix_vector_dot(x,y):assertlen(x.sha......
  • RISCV内核中断优先级/Priority
    一、讲解中断优先级分为抢占优先级和响应优先级。配置参数越小,则说明其优先级别越高。抢占:是指可以打断其他中断函数的属性。出现该属性时会出现中断嵌套;响应:是指抢占优先级相同情况下,则优先执行响应优先级高的中断;二、举例序号中断名称优先级1TMR1102TMR21......
  • 模板矩阵类
    template<size_trow,size_tcolumn,typenameT=XDecimal>classXMatrix{public:XMatrix():_row(row),_column(column){_vals=newT[row*column]{0.0};}virtual~XMatrix(){delete[]_va......
  • 矩阵类
    头文件:classX_MATH_EXPORTXMatrix{public:XMatrix()=delete;XMatrix(size_trow,size_tcolumn,XDecimalval);XMatrix(size_trow,size_tcolumn,constXDecimalvals[]);XMatrix(size_trow,size_tcolumn,std::in......
  • Linux调度器:进程优先级
    一、前言本文主要描述的是进程优先级这个概念。从用户空间来看,进程优先级就是nicevalue和schedulingpriority,对应到内核,有静态优先级、realtime优先级、归一化优先级和动态优先级等概念,我们希望能在第二章将这些相关的概念描述清楚。为了加深理解,在第三章我们给出了几个典型数......