- 题目描述:
-
在一个M * N的矩阵中,所有的元素只有0和1,从这个矩阵中找出一个面积最大的全1子矩阵,所谓最大是指元素1的个数最多。
- 输入:
-
输入可能包含多个测试样例。
对于每个测试案例,输入的第一行是两个整数m、n(1<=m、n<=1000):代表将要输入的矩阵的大小。
矩阵共有m行,每行有n个整数,分别是0或1,相邻两数之间严格用一个空格隔开。
- 输出:
-
对应每个测试案例,输出矩阵中面积最大的全1子矩阵的元素个数。
- 样例输入:
-
2 2 0 0 0 0 4 4 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0
- 样例输出:
-
0
4
-
思路:和之前zjnu1735差不多,只不过这里求的是最大面积,用q[ ][0]表示高度,q[ ][1]表示下标就行了。
-
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<string> #include<bitset> #include<algorithm> using namespace std; typedef long long ll; typedef long double ldb; #define inf 99999999 #define pi acos(-1.0) #define maxn 1005 int gra[maxn][maxn]; int h[maxn][maxn],l[maxn],r[maxn]; int q[111111][2]; int main() { int n,m,i,j; while(scanf("%d%d",&n,&m)!=EOF) { memset(h,0,sizeof(h)); for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ scanf("%d",&gra[i][j]); if(gra[i][j]==0)h[i][j]=0; else{ h[i][j]=1; if(i>1){ h[i][j]+=h[i-1][j]; } } } } int front,rear; int maxx=0; for(i=1;i<=n;i++){ front=1;rear=0; for(j=1;j<=m;j++){ while(front<=rear && q[rear][0]>=h[i][j]){ rear--; } if(rear==0){ l[j]=1; } else{ l[j]=q[rear][1]+1; } rear++; q[rear][0]=h[i][j]; q[rear][1]=j; } front=1;rear=0; for(j=m;j>=1;j--){ while(front<=rear && q[rear][0]>=h[i][j]){ rear--; } if(rear==0){ r[j]=m; } else{ r[j]=q[rear][1]-1; } maxx=max(maxx,h[i][j]*(r[j]-l[j]+1) ); rear++; q[rear][0]=h[i][j]; q[rear][1]=j; } } printf("%d ",maxx); } return 0; }