SHU1954 Dispsy loves flowers

Description

Dipsy是一个非常喜欢花的孩子,他现在在一个n * m的花园里,花园里布满了花,不幸的是,花园里的某些地方被放上了石头。Dipsy希望能够在花园里找到一个位置,使得自己看到的花尽可能多(当然他只能往前后左右四个方向看啦),要注意的是,石头太高啦,因此,如果从某个方向看到了石头,那么石头后面的花就看不到了,当然,他也太小了爬不上石头(唔,就是他不能选择石头所在的位置啦!)

tips:自己所处位置的花是看不到的!!!

他的数学好像有点不太好,因此,只能拜托你来解决这个问题了,你要负责帮他计算出他最多能看到多少朵花。

Input

多组数据,第一行有一个整数T,代表数据组数,接下来有T组数据。(T <= 10)

每组数据第一行有两个整数n,m,代表了花园的长和宽。(1 <= n <= 1000, 1 <= m <= 1000)

然后有n行m列的矩阵表示花园的状态,其中"."代表花,“x"代表石头。

Output

对于每组数据,输出一个正整数,代表该组数据能够看到的最大花数。

Sample Input

2
2 2
..
x.
4 4
x..x
....x
.x.x
xxx

Sample Output

2
5


做法如下(引用了校ACM群的题解)

举个栗子,要知道每个点到右边的最长距离,对每行依次从右向左遍历,如果当前点的右边是石头,那么当前点的值就是0,否则就是右边的点的值+1。

 

                                    0

                             0     0

                      0     1     0

              1      0     1     0

       2     1      0     1     0

坑点:1. 给的题解不是说可以先4*n^2预处理每个点四个方向的值然后遍历求每个点四个方向的值,取最大的嘛!但用这个方法,我TLE了好几次,看了队友的代码,发现他用了2*n^2,我get到了好办法!

2.四个方向的值相加时注意判断该点是不是石头,是石头的不要加,因为是石头四个方向也会有值哒!

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char map[1005][1005];
int lef[1005][1005],righ[1005][1005],up[1005][1005],down[1005][1005],all[1005][1005];
int main(void)
{
    int t,i,j,m,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&m,&n);
        getchar();
        memset(all,0,sizeof(all));
        memset(lef,0,sizeof(lef));
        memset(righ,0,sizeof(righ));
        memset(down,0,sizeof(down));
        memset(up,0,sizeof(up));
        for(i=1;i<=m;i++)
        {
            for(j=1;j<=n;j++)
            {
                scanf("%c",&map[i][j]);
            }
            getchar();
        }
        for(i=1;i<=m;i++)
            for(j=1;j<=n;j++)
            {
                if(map[i][j-1]=='.')
                    lef[i][j]=lef[i][j-1]+1;
                else
                    lef[i][j]=0;
                if(map[i-1][j]=='.')
                    up[i][j]=up[i-1][j]+1;
                else
                    up[i][j]=0;
                if(map[i][j]=='.')
                   all[i][j]+=lef[i][j]+up[i][j];
            }
        int max=0;
        for(i=m;i>=1;i--)
            for(j=n;j>=1;j--)
            {
                if(map[i][j+1]=='.')
                    righ[i][j]=righ[i][j+1]+1;
                else
                    righ[i][j]=0;
                if(map[i+1][j]=='.')
                    down[i][j]=down[i+1][j]+1;
                else
                    down[i][j]=0;
                if(map[i][j]=='.')
                    all[i][j]+=righ[i][j]+down[i][j];
                if(max<all[i][j])
                    max=all[i][j];
            }
        printf("%d\n",max);
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值