Problem 1408 位图
Accept: 502 Submit: 2281
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
现在我们给出一个n*m的黑白位图,n为行数,m为列数,且该位图中至少含有一个白色的像素。我们用(i,j)来表示第i行第j列的像素,并且定义两像素点p1=(i1,j1)和p2=(i2,j2)之间的距离为:d(p1,p2)=|i1-i2|+|j1-j2|。
对于任意给定的位图,计算出位图中每个像素到与它最近的白色像素之间的距离。
对于任意给定的位图,计算出位图中每个像素到与它最近的白色像素之间的距离。
Input
本题有多组输入数据,每组数据第一行包含两个整数n,m,用空格分开,1<=n,m<=182。之后的n行每行包含一个长度为m的由0和1组成的字符串,即第i行第j个字符如果为"1",那么表示像素(i,j)为白的,否则为黑的。
Output
对于每组数据,输出包含n行,第i行的第j个数字为f(i,j),表示像素(i,j)到最近的白色像素的距离。每行内的数字用空格分开。
Sample Input
3 4
0001
0011
0110
Sample Output
3 2 1 0
2 1 0 0
1 0 0 1
分析:广度优先搜索,刚开始写的代码老师内存超限,看了讨论知道,不能从每个0去找1,而应该从1去找0,这样比较节约内存和时间
memory limit exceed 代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn=200;
int flag[200][200];
char a[200][200];
int n,m;
int direction[4][2]={{0,-1},{0,1},{-1,0},{1,0}};
int ans[40000],num;
struct point
{
char value;
int x,y;
int step;
};
void bfs(char value,int row,int col,int step)
{
int x,y;
point v,w,top;
v.value=value;
v.x=row;
v.y=col;
v.step=step;
queue<point> q;
q.push(v);
flag[row][col]=step+1;
while(!q.empty())
{
top=q.front(); q.pop();
if(top.value=='1')
{
ans[num]=top.step;
num++;
break;
}
for(int i=0;i<4;i++)
{
x=top.x+direction[i][0];
y=top.y+direction[i][1];
if(x>=0 && x<n && y>=0 && y<m && !flag[x][y])
{
w.value=a[x][y];
w.x=x;
w.y=y;
w.step=top.step+1;
q.push(w);
}
}
}
}
int main()
{
while(cin>>n>>m)
{
num=0;
memset(ans,0,sizeof(ans));
for(int i=0; i<n; i++)
scanf("%s",a[i]);
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
if(a[i][j]=='1')
{
ans[num]=0;
num++;
}
else
{
memset(flag,0,sizeof(flag));
bfs(a[i][j],i,j,0);
}
}
}
for(int i=0; i<num; i++)
{
cout<<ans[i];
if((i+1)%m==0) cout<<endl;
else cout<<" ";
}
}
return 0;
}
AC代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn=200;
int flag[200][200];
char a[200][200];
int n,m;
int direction[4][2]={{0,-1},{0,1},{-1,0},{1,0}};
int ans[200][200];
struct point
{
char value;
int x,y;
int step;
};
queue<point> q;
void bfs()
{
while(!q.empty())
{
point top=q.front(); q.pop();
for(int i=0;i<4;i++)
{
int x=top.x+direction[i][0];
int y=top.y+direction[i][1];
if(x>=0 && x<n && y>=0 && y<m && !flag[x][y])
{
flag[x][y]=1;
ans[x][y]=top.step+1;
point w;
w.value=a[x][y];
w.x=x;
w.y=y;
w.step=top.step+1;
q.push(w);
}
}
}
}
int main()
{
while(cin>>n>>m)
{
point cur;
memset(ans,0,sizeof(ans));
memset(flag,0,sizeof(flag));
for(int i=0; i<n; i++)
scanf("%s",a[i]);
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
if(a[i][j]=='1')
{
flag[i][j]=1;
ans[i][j]=0;
cur.value='1';
cur.x=i;
cur.y=j;
cur.step=0;
q.push(cur);
}
}
}
bfs();
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
cout<<ans[i][j];
if(j!=m-1) cout<<" ";
}
cout<<endl;
}
}
return 0;
}