[BZOJ 2252][2010Beijing wc]矩阵距离

Description

 

假设我们有矩阵,其元素值非零即1

a11…… a1m

…………….

an1…….anm

 

定义aijakl之间的距离为D(aij,akl)=abs(i-k)+abs(j-L) 

Input

输入文件的第一行为两个整数,分别代表n和m。
接下来的n行,第i行的第 j个字符代表aij

Output

输出包含N行,每行M个用空格分开的数字,其中第i行第J个数字代表
Min(D(aij,axy) 1<=x<=N 1<=y<m,且axy=1

Sample Input

3 4
0001
0011
0110

Sample Output

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

HINT

对于100%的数据,满足 0 <  m n <=1000

Source

BFS,为了简便可以逆向思维,从是1的点反过来搜,可以不用queue,用两个数组x[]、y[]模拟队列就行,再者要注意判重合,还要重视是1的点的dis数组初始化为0,被坑了,艹。。

#include <stdio.h>
#include <string.h>
#define MAXN 1050
int xx[4]={1,-1,0,0},yy[4]={0,0,1,-1}; //四个方向你懂的
int dis[MAXN][MAXN],map[MAXN][MAXN],n,m,cnt=1,x[1000*MAXN],y[1000*MAXN]; //dis[i][j]=Min(D(aij,axy),cnt=1的个数,x[i]=第i个1的x坐标,y同理
char in[MAXN];
void bfs() //由是1的点为起点bfs,下面的思路类似于队列
{
	int t=0;
	while(t<cnt)
	{
		int i=x[t],j=y[t],k; //获得队首点坐标
		for(k=0;k<4;k++) //四个方向走
		{
			int nowx=i+xx[k],nowy=j+yy[k];
			if(nowx<1||nowx>n||nowy<1||nowy>m||dis[nowx][nowy]!=-1) continue; //移动后越界了或是已经搜索过,跳过
			dis[nowx][nowy]=dis[i][j]+1; //移动了一步,更新距离=dis(i,j)+1
			x[cnt]=nowx; //移动后的点入队
			y[cnt]=nowy;
			cnt++;
		}
		t++; //队首的点四个方向走完后出队
	}
}
int main()
{
	int i,j;
	memset(dis,-1,sizeof(dis));
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++)
	{
		scanf("%s",in);
		for(j=1;j<=m;j++)
			if(in[j-1]=='1')
			{
				dis[i][j]=0; //注意初始化!!!妈的。。。
				x[cnt]=i;
				y[cnt]=j;
				cnt++;
			}
	}
	bfs();
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
			printf("%d ",dis[i][j]);
		printf("\n");
	}
	return 0;
}


 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值