32. [POI1999] 位图
★ 输入文件:bit.in
输出文件:
bit.out
简单对比
时间限制:1 s 内存限制:128 MB
【问题描述 】
给定一个 n*m 的矩形位图,位图中的每个像素不是白色就是黑色,但至少有一个是白色的。第 i 行、第 j 列的像素被称作像素 (i, j) 。两个像素 p1 = (i1, j1) , p2 = (i2, j2) 之间的距离定义为: d(p1, p2) = |i1 - i2| + |j1 - j2|.
【任务 】
编一个程序完成以下操作:
1 .从输入文件中读入此位图的有关信息。
2 .对于每个像素,计算此像素与离其最近的“白像素”的距离。
3 .将结果写到输出文件里面。
【输入格式 】
输入文件的第一行包含两个整数 n, m ( 1 ≤ n ≤ 182, 1 ≤ m ≤ 182 ),用一个空格隔开。接下来 n 行,每一行都包含一个长度为 m 的 01 串;第 i+1 行,第 j 列的字符若为 1 ,则像素 (i, j) 是白色的;否则是黑色的。
【输出格式 】
输出文件包含 n 行 , 每行有 m 个用空格隔开的整数。第 i 行、第 j 列的整数表示 (i, j) 与离它最近的白像素之间的距离
【样例输入】
bit.in
3 4
0001
0011
0110
【样例输出】
bit.out
3 2 1 0
2 1 0 0
1 0 0 1
简单BFS+DP,直接以白色点向外拓展,只有下个节点是黑色点且 所得距离小于以前搜索到这个点的距离。
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 200;
char map[maxn][maxn];
bool vis[maxn][maxn];
int dp[maxn][maxn];
int dx[]={0,1,-1,0};
int dy[]={1,0,0,-1};
int n,m;
bool check(int x,int y){
return x>=0&&x<n&&y>=0&&y<m;
}
void bfs(int sx,int sy){
queue<int > q;
memset(vis,false,sizeof(vis));
q.push(sx); q.push(sy);
vis[sx][sy]=true;
while(!q.empty()){
int x=q.front(); q.pop();
int y=q.front(); q.pop();
for(int i=0;i<4;i++){
int nx=x+dx[i]; int ny=y+dy[i];
int s=abs(nx-sx)+abs(ny-sy);
if(check(nx,ny)&&map[nx][ny]=='0'&&!vis[nx][ny]&&dp[nx][ny]>s){
vis[nx][ny]=true;
dp[nx][ny]=s;
q.push(nx); q.push(ny);
}
}
}
}
int main(){
freopen("bit.in","r",stdin);
freopen("bit.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++) scanf("%s",map[i]);
for(int i=0;i<n;i++) for(int j=0;j<m;j++) dp[i][j]=100000;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++)
if(map[i][j]=='1'){
dp[i][j]=0;
bfs(i,j);
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m-1;j++)
printf("%d ",dp[i][j]);
printf("%d\n",dp[i][m-1]);
}
return 0;
}