九度1497:面積最大的全1子矩陣 (單調隊列,單調棧)

題目描述:

在一個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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章