您的位置:首页 > 其它

SHU1954 Dispsy loves flowers

2015-12-20 23:27 148 查看

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: