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,y2 where 1≤x1≤x2≤N and 1≤y1≤y2≤M. Then, the rectangle is composed of all the cell (x, y) where x1≤x≤x2 and y1≤y≤y2. 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.
1≤N,M≤1000
N×M≥2
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 ",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 ",m2); 45 return 0; 46 }