这题我们可以想到权重和矩阵,由于当01矩阵A[i][j]=1时,正数矩阵B[i][j]=0,与其上下左右相邻的A[i][j]=0对应的B[i][j]=1,可以联想到多元矩阵
给定一个 NN 行 MM 列的 0101 矩阵 AA,A[i][j]A[i][j] 与 A[k][l]A[k][l] 之间的曼哈顿距离定义为:
dist(A[i][j],A[k][l])=|i−k|+|j−l|dist(A[i][j],A[k][l])=|i−k|+|j−l|
输出一个 NN 行 MM 列的整数矩阵 BB,其中:
B[i][j]=min1≤x≤N,1≤y≤M,A[x][y]=1dist(A[i][j],A[x][y])B[i][j]=min1≤x≤N,1≤y≤M,A[x][y]=1dist(A[i][j],A[x][y])
输入格式
第一行两个整数 N,MN,M。
接下来一个 NN 行 MM 列的 0101 矩阵,数字之间没有空格。
输出格式
一个 NN 行 MM 列的矩阵 BB,相邻两个整数之间用一个空格隔开。
数据范围
1≤N,M≤10001≤N,M≤1000
输入样例:
3 4
0001
0011
0110
输出样例:
3 2 1 0
2 1 0 0
1 0 0 1
我们要透过现象看本质,不仅仅是简单的把每个A[i][j]所对应的B[i][j]求出来,当然这是最终目的,但核心是权重加权和bfs问题
附上我最初暴力搜索为过的代码:
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
int x;
int y;
};
const int N=1005;
int n,m;
char a[N][N];
int b[N][N];
node c[N];
int main(){
cin>>n>>m;
int k=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
if(a[i][j]=='1'){
k++;
c[k]={i,j};
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]=='1'){
b[i][j]=0;
continue;
}
b[i][j]=10001;
for(int t=1;t<=k;t++){
int dist=abs(i-c[t].x)+abs(j-c[t].y);
b[i][j]=min(b[i][j],dist);
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<m;j++){
cout<<b[i][j]<<" ";
}
cout<<b[i][m]<<endl;
}
return 0;
}
对比上面和下面的代码,可以很明显的看出多元bfs方式解这道题的好处,
最终代码:
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int N=1005;
int n,m;
char a[N][N];
int b[N][N];
bool flag[N][N];
struct node{
int x1;
int y1;
};
queue<node> qu;
int s[]={1,0,-1,0};
int x[]={0,-1,0,1};
void bfs(){
while(!qu.empty()){
node now=qu.front();
qu.pop();
for(int i=0;i<4;i++){
int xx=now.x1+s[i];
int yy=now.y1+x[i];
if(flag[xx][yy]){
b[xx][yy]=b[now.x1][now.y1]+1;
flag[xx][yy]=false;
qu.push(node{xx,yy});
}
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
flag[i][j]=true;
if(a[i][j]=='1'){
flag[i][j]=false;
b[i][j]=0;
qu.push(node{i,j});
}
}
}
bfs();
for(int i=1;i<=n;i++){
for(int j=1;j<m;j++)
cout<<b[i][j]<<" ";
cout<<b[i][m]<<endl;
}
return 0;
}