H - 2番目のフィールドのトレーニングゲームオフ第2の大矩形牛

H - 第2の大長方形

 

 

 

 

 

トピック分析 :あなたのを与えるために、 N * M 01 行列は、あなたが二番目に大きいが全てです含まれてい見つけることができます「1」行列のサイズ。 これは、必要はO(n ^ 2)二番目に大きい行列を見つけるための方法を

第2の大行列の2つのケースがある: 1. 第2の大フル1つの行列   2 行列の最大のサブ行列の最大

例:1.

0111

0111

1111

1111

1111

1111     その答えは16   

2。

111111

111111 これの答えは2 * 5 の長方形10

 

だから我々は唯一の答えシーケンス、長方形の大きさとその最大のサブ行列の最大の大きさは、その答えは、ソート順序で、二番目に大きいが答えであるシーケンスを構築する必要があります

それでは、どのようはO(n ^ 2)最大の行列を見つけるために:

我们需要对遍历到的当前行的每个元素记录一个h[j],记录到这一行的这一列向上有多少个连续的1。然后记录一个l[j] , r[j]分别记录这个元素可以构成的矩形向左,向右最多可以到哪里。如图:高度为h[j]的矩形只能使用比它更高的。处理l[],r[]的复杂度为O(m)

 

 

 

代码:

#include <bits/stdc++.h>

using namespace std;
int c[1006][1006];
int l[1006],r[1006],h[1006];
int n,m;
int tot,p[4006000];
char str[1006];
set<pair<int,int> > s[1005];
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%s",str+1);
        for(int j=1;j<=m;j++){
            c[i][j]=str[j]-'0';
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){  //h[]
            if(c[i][j])h[j]++;
            else h[j]=0;
        }
        for(int j=1;j<=m;j++){ //l[]
            l[j]=j;
            while(l[j]>1&&h[j]<=h[l[j]-1]){
                l[j]=l[l[j]-1];
            }
        }
        for(int j=m;j>=1;j--){ //r[]
            r[j]=j;
            while(r[j]<m&&h[j]<=h[r[j]+1]){
                r[j]=r[r[j]+1];
            }
        }
        for(int j=1;j<=m;j++){
            if(s[i].find(make_pair(l[j],r[j]))==s[i].end()){
                p[++tot] = h[j]*(r[j]-l[j]+1);
                s[i].insert(make_pair(l[j],r[j]));
                if(r[j]-l[j]+1 > h[j]){  //如果矩形的横边 大于竖边 那么它最大的子矩阵是(横边-1)*竖边
                    p[++tot] = h[j] * (r[j] - l[j]);
                }
            }
        }
    }
    sort(p+1,p+1+tot);
    if(tot<=1)printf("0\n");
    else printf("%d\n",p[tot-1]);
    return 0;
}

 

おすすめ

転載: www.cnblogs.com/hao-tian/p/11220394.html