【hihoCoder】1973 : 灯塔问题 **初来乍到,请多关照**

原文链接:

https://hihocoder.com/problemset/problem/1973

问题描述

给定一个NxM的方格矩阵,其中某些方格中包含有一座灯塔。
已知灯塔可以照射到上下左右与它在同一排或同一列的方格,除非被矩阵边缘或者另一座灯塔阻挡。
请你计算矩阵中每一个不包含灯塔的方格,同时被多少座灯塔照射到?

输入

第一行包含2个整数N和M。
以下N行每行包含M个字符,代表方格矩阵。其中字符B代表灯塔,O代表空方格。
对于80%的数据,1 <= N, M <= 100
对于100%的数据,1 <= N, M <= 1000

输出

一个NxM的字符矩阵。
将输入的矩阵中的每一个字符O替换为一个0~4的数字,代表该方格同时被多少座灯塔照射到。B字符保持不变。

样例输入

4 4  
OOOO
BOBO
OOOO
OBBO

样例输出

1110
B3B1
1120
2BB1

思路分析:

1.题目输入中给出平面的行数和列数,能直接确定大小。
2.用一个数组存储(代码中的b)存储灯塔位置,搜索灯塔时可直接定位。
3.将字符串构成的平面与二维数组(int型)进行映射:灯塔位置赋值为-1,其他位置初始为0(设成0的目的是方便统计被照到的灯塔数),计算时利用数组b直接定位灯塔。然后根据此点向上下左右四个方向延伸,直到触碰其他灯塔(遇到-1)时或者二维数组边缘时结束延伸(这也就对应了被挡住的灯塔无法照射的要求),所经过的空白点处该值加1即可,代表被一个灯塔照到。
4.输出时,直接按格式输出二维数组即可。这里要注意的是,当某个元素为-1(灯塔)的时候要输出“B”。

代码:

在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
int a[1001][1001],b[1001][2];
int m,n,i,j;
int k=0;
int main()
{
    string s;//按行读入字符串
    scanf("%d%d\n",&n,&m);
    for(i=0;i<n;i++)
    {
        getline(cin,s);
        for(j=0;j<m;j++)
        {
            if(s[j]=='O')a[i][j]=0;//空白区域初始值
            if(s[j]=='B')
            {
                b[k][0]=i;//存储灯塔位置信息
                b[k++][1]=j;
                a[i][j]=-1;//灯塔
            }
        }
    }
    for(i=0;i<k;i++)//按每个灯塔位置搜索
    {
        for(j=b[i][1]-1;j>=0;j--)//向上,循环到数组边界,下同
        {
            if(a[b[i][0]][j]==-1)break;//遇到灯塔结束,下同
            a[b[i][0]][j]++;
        }
        for(j=b[i][1]+1;j<=n-1;j++)//向下
        {
            if(a[b[i][0]][j]==-1)break;
            a[b[i][0]][j]++;
        }
        for(j=b[i][0]-1;j>=0;j--)//向左
        {
            if(a[j][b[i][1]]==-1)break;
            a[j][b[i][1]]++;
        }
        for(j=b[i][0]+1;j<=m-1;j++)//向右
        {
            if(a[j][b[i][1]]==-1)break;
            a[j][b[i][1]]++;
        }
    }
    for(i=0;i<n;i++)
        for(j=0;j<m;j++)
    {
        if(a[i][j]==-1)cout<<"B";//遇到灯塔输出
        else
            cout <<a[i][j];
        if(j==m-1)
            cout <<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值