TYVj1939 玉蟾宫
玉蟾宫
题目描述:
在一个01(RF)中,找出一个只包含1(F)的最大矩阵,求出该矩阵的面积。
思路:
题目的数据范围是一千,所以n^3就会爆炸,所以我们考虑n^2的做法。
我们可以用一个二维数组来记录在该点的上面有多少个F(高度),然后求出该点左边和右边第一个低于该点的点,用两点之差乘上该点的高度,就是结果。
有了大致思路,我们就可以考虑优化,因为如果是向循环找点的话就太慢了。
然后就想到了单调栈。
不断用单调栈来找出一个点的左右两点,更新ans,,最后输出ans*3就可以了。
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #define N 1010 5 using namespace std; 6 int l[N],r[N],dis[N],sum[N][N],top,n,m,ans=-1; 7 char a[1]; 8 void find(int x){ 9 sum[x][0]=sum[x][m+1]=-1; 10 top=0; 11 for(int i=1;i<=m+1;++i){ 12 while(top&&sum[x][dis[top]]>sum[x][i]) 13 r[dis[top--]]=i; 14 dis[++top]=i; 15 } 16 top=0; 17 for(int i=m;i>=0;i--){ 18 while(top&&sum[x][dis[top]]>sum[x][i]) 19 l[dis[top--]]=i; 20 dis[++top]=i; 21 } 22 for(int i=1;i<=m;++i) 23 ans=max(ans,(r[i]-l[i]-1)*sum[x][i]); 24 } 25 int main(){ 26 scanf("%d%d",&n,&m); 27 for(int i=1;i<=n;++i) 28 for(int j=1;j<=m;++j){ 29 scanf("%s",a); 30 if(a[0]=='F') 31 sum[i][j]=sum[i-1][j]+1; 32 } 33 for(int i=1;i<=n;++i) 34 find(i); 35 printf("%d",ans*3); 36 return 0; 37 }