Time Limit: 5000MS Memory Limit: 131072K
Total Submissions: 10513 Accepted: 3703
Case Time Limit: 2000MS
Description
Given a m-by-n (0,1)-matrix, of all its submatrices of all 1’s which is the largest? By largest we mean that the submatrix has the most elements.
Input
The input contains multiple test cases. Each test case begins with m and n (1 ≤ m, n ≤ 2000) on line. Then come the elements of a (0,1)-matrix in row-major order on m lines each with n numbers. The input ends once EOF is met.
Output
For each test case, output one line containing the number of elements of the largest submatrix of all 1’s. If the given matrix is of all 0’s, output 0.
Sample Input
2 2
0 0
0 0
4 4
0 0 0 0
0 1 1 0
0 1 1 0
0 0 0 0
Sample Output
0
4
解题思路
题意:求仅由0,1组成的矩阵中,全部由1组成的小矩阵的最大面积。
思路:这个是 类型二.的升级版,都是用了压行的思想把多行压成 一行,降维后当成1维的处理,区别是这个是枚举底行。
对任意一个位置
i
i
i,我们需要找到其左右边第一个小于arr[i]的数的位置
p
1
,
p
2
p1,p2
p1,p2,则位置i对应的面积是
(
p
2
−
p
1
−
1
)
∗
a
r
r
[
i
]
(p2 - p1 - 1)* arr[i]
(p2−p1−1)∗arr[i]
需要一个辅助栈,压入弹出规则如下:(注意只压入下标)
- 若当前数 arr[i] 大于或等于栈顶数arr[j],压入当前数的下标i
- 否则,弹出栈顶数j。此时栈顶数为k,继续判断。
只在情况 2 2 2中计算想要的面积。对弹出的栈顶数j,其右边第一个比他小的数为 a r r [ i ] arr[i] arr[i], 其左边第一个比他小的数为 a r r [ k ] arr[k] arr[k]. 则对j来说,其对应的面积为 ( i − k − 1 ) ∗ a r r [ j ] (i - k - 1)* arr[j] (i−k−1)∗arr[j]
我给 b [ 0 ] b[0] b[0]和 b [ m + 1 ] b[m+1] b[m+1]分别设置为 − 1 -1 −1,目的是让吗每个元素出栈后,任然存在栈顶元素,作为 t m p tmp tmp元素能拓展到的最左,和每个元素都能出栈,保证每个元素对应的柱子都能计算到。
代码
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int n,m,a[2010][2010],b[2020],q[2020],top,ans;
int main(){
while(scanf("%d",&n)!=EOF)
{
memset(b,0,sizeof(b));
scanf("%d",&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
b[0]=b[m+1]=-1;
ans=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i][j]==1)
b[j]+=1;
else
b[j]=0;
}
memset(q,0,sizeof(q));
top=0;
for(int j=0;j<=m+1;j++)
{
while(top>0&&b[q[top]]>b[j])
{
int tmp=b[q[top]];
top--;
ans=max(ans,tmp*(j-q[top]-1));
}
q[++top]=j;
}
}
printf("%d\n",ans);
}
}