牛客网(暑假集训#2)H - Second Large Rectangle

Description

Given a N×M binary matrix. Please output the size of second large rectangle containing all "1".
Containing all "1" means that the entries of the rectangle are all "1".

A rectangle can be defined as four integers x1,y1,x2,ywhere 1x1x2and 1≤y1≤y2≤M. Then, the rectangle is composed of all the cell (x, y) where x1xxand y1yy2. If all of the cell in the rectangle is "1", this is a valid rectangle.
Please find out the size of the second largest rectangle, two rectangles are different if exists a cell belonged to one of them but not belonged to the other.

Input

The first line of input contains two space-separated integers N and M.
Following N lines each contains M characters cij.

1N,M1000

N×M2

cij∈"01"

Output

Output one line containing an integer representing the answer. If there are less than 2 rectangles containning all "1", output "0".

Sample Input 1

1 2

01

Sample Output 1

0

Sample Input 2

1 3

101

Sample Output 2

1

Resume

01矩阵中求第二大矩形。

Analysis

首先考虑求最大矩形:

不妨考虑以第i行为底边的矩形,那么就转化成直方图求最大矩形面积。

如图


当我们遇到第三列时,第二列的高度已经不能拓展,因此将其清算掉,同时将第三列高度加入栈中。

即使用单调栈维护所有高度中最靠右且小于当前高度的位置(注意单调)。

进而考虑求第二大,情况有二,所有完整的尽量大的矩形中第二大,或者尽量大的矩形去掉一行或者一列。由于我们按行以此求解,只需要额外考虑去掉一列的情况就OK。

另:可以使用滚动数组边读入边求解。

Code

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1010;
 4 int n,m,m1,m2,h[N],s[N],top;
 5 bool gra[N][N];
 6 
 7 inline int Max(int a,int b){return a>b?a:b;}
 8 
 9 int main(){
10     scanf("%d %d",&n,&m);
11     for(int i=1;i<=n;i++){
12         getchar();
13         for(int j=1;j<=m;j++){
14             gra[i][j] = getchar()-'0';
15         }
16     }
17 
18     for(int i=1;i<=n;i++){
19         top = 0;
20         int ans;
21         for(int j=1;j<=m+1;j++){
22             h[j] = gra[i][j]?h[j]+1:0;
23             while(top && h[j] <= h[s[top]]){
24                 //printf("!%d %d\n",i,s[top-1]);
25                 ans = h[s[top]]*(j-1-s[top-1]);
26                 if(ans > m1){
27                     m2 = m1;
28                     m1 = ans;
29                     ans -= h[s[top]];
30                     if(ans > m2){
31                         m2 = ans;
32                     }
33                 }
34                 else if(ans > m2){
35                     m2 = ans;
36                 }
37                 
38                 top--;
39             }
40             s[++top] = j;
41         }
42     }
43 
44     printf("%d\n",m2);
45     return 0;
46 }
View Code

Appendix

补题网址

猜你喜欢

转载自www.cnblogs.com/pisceskkk/p/11229105.html