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".
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\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 }