- 題目描述:
-
在一個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\n",maxx); } return 0; }