【八中测试】位图

位图

时间限制: 1 Sec
内存限制: 64 MB

题目描述

给出一个大小为n行*m列的矩形位图。该位图的每一个象素点不是白色就是黑色,但是至少有一个象素点是白色。在i行j列的象素点我们称为点(i,j)。两个象素点p1=(i1,j1)和p2=(i2,j2)之间的距离定义如下:
d(p1,p2)=|i1-i2|+|j1-j2|.

现在的任务是:对于每一个象素点,计算它到最近的白色点的距离。如果它本身是白色点,距离为0。

输入

第1行:2个整数n,m(1<=n <=182,1<=m<=182)
接下来n行,每一行有一个长度为m的0/1字符串,描述一行象素点。如果点(i,j)为白色,则值为1,否则值为0。

输出

共n行,每行有m个整数,数之间用1个空格分开,分别表示对应的象素点距离白色点的距离。

样例输入

3 4
0001
0011
0110

样例输出

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

解析

这道题大多数同学都是用搜索来完成的,那么我们首先来讲述一下搜索该如何进行。思路如下:我们可以从1开始搜,只不过用了SPFA的思想,即如果成功更新ans[i][j];那么才继续搜。

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int n,m;int a[155][155];
int ans[155][155];
int mx[4]={0,0,1,-1},my[4]={1,-1,0,0};
int qx[150*151],qy[150*151];
int main(){
    memset(ans,60,sizeof(ans));
    scanf("%d%d",&n,&m);int head=0,tail=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            scanf("%d",&a[i][j]);
            if(a[i][j]){
                ans[i][j]=0;
                qx[++tail]=i;qy[tail]=j;
                ————————————————>把1先扔进队列
            }
        }
    }
    int x,y;
    while(tail>head){
        head++;x=qx[head];y=qy[head];
        for(int i=0;i<4;i++){
            if((x+mx[i]>0&&x+mx[i]<=n&&y+my[i]>0&&y+my[i]<=m)——————————————>边界  &&((a[x+mx[i]][y+my[i]]!=1)&&(ans[x+mx[i]][y+my[i]]>ans[x][y]+1))){
其实可以不用这个。。 但这个是核心
                qx[++tail]=x+mx[i];qy[tail]=y+my[i];
                ans[x+mx[i]][y+my[i]]=ans[x][y]+1;
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)cout<<ans[i][j]<<" ";
        cout<<endl;
    }
    return 0;
}

我们还有一种方法,但这种方法近乎于枚举(但是却AC了,玄学……):首先我们可以将每一排的最短路求出,即按如下所示:

0 0 0 1 0
--->3 2 1 0 1

由于我们这道题是只能向四周进行移动,我们现在已将每一排的最短路求出,即横向(左右向),所以我们现在就差竖向,所以我们可以再进行一次枚举,将竖向的最短路求出。如此,便得到答案,只需要输出答案即可。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 200
int m,n;
int map[N][N];
void L(int i,int j)
{
    for(int l=1;l<=n;l++)
    map[i][j]=min(map[i][j],abs(i-l)+map[l][j]);
}
void R(int i,int j)
{
    for(int l=1;l<=m;l++)
    map[i][l]=min(map[i][l],abs(l-j));
}
int main()
{
    char s[N][N];
    memset(map,0x7f,sizeof map);
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s[i]+1);
        for(int j=1;j<=m;j++)
            if(s[i][j]=='1') map[i][j]=0,R(i,j); 
    }
    /*for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(j==m) printf("%d\n",map[i][j]);
            else printf("%d ",map[i][j]);
        }
    }*/
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            L(i,j);
            if(j==m) printf("%d\n",map[i][j]);
            else printf("%d ",map[i][j]);
        }
    }
} 

猜你喜欢

转载自blog.csdn.net/qq_37862149/article/details/79726450