题目描述
Given a N×MN \times MN×M binary matrix. Please output the size of second large rectangle containing all "1"\texttt{"1"}"1".
Containing all "1"\texttt{"1"}"1" means that the entries of the rectangle are all "1"\texttt{"1"}"1".
A rectangle can be defined as four integers x1,y1,x2,y2x_1, y_1, x_2, y_2x1,y1,x2,y2 where 1≤x1≤x2≤N1 \leq x_1 \leq x_2 \leq N1≤x1≤x2≤N and 1≤y1≤y2≤M1 \leq y_1 \leq y_2 \leq M1≤y1≤y2≤M. Then, the rectangle is composed of all the cell (x, y) where x1≤x≤x2x_1 \leq x \leq x_2x1≤x≤x2 and y1≤y≤y2y_1 \leq y \leq y2y1≤y≤y2. If all of the cell in the rectangle is "1"\texttt{"1"}"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.
输入描述:
The first line of input contains two space-separated integers N and M.
Following N lines each contains M characters cijc_{ij}cij.
1≤N,M≤10001 \leq N, M \leq 10001≤N,M≤1000
N×M≥2N \times M \geq 2N×M≥2
cij∈"01"c_{ij} \in \texttt{"01"}cij∈"01"
输出描述:
Output one line containing an integer representing the answer. If there are less than 2 rectangles containning all "1"\texttt{"1"}"1", output "0"\texttt{"0"}"0".
输入
1 2
01
输出
0
输入
1 3
101
输出
1
题意:
给出只包含0和1的矩形长和宽,计算出第二大全1矩阵的面积。
思路:
a.先简化成求最大全1矩阵面积:
1、对01矩阵的每一行求列(行)前缀和
2、在每一行中找每个元素的左右边界
例如:
输入矩阵:
1110
1110
0011
0011
第一步:(求列前缀和)
1110
2220
0031
0042
第二步:找左右边界(取第四行 0042 为例)
为便于观察,先画出分布图
对于图中每一个列元素,以其为高的最大矩形边长分别是:
l[1]=0,r[1]=5 S=0*(5-0-1)=0
l[2]=0,r[2]=5 S=0*(5-0-1)=0
l[3]=2,r[3]=4 S=4*(4-2-1)=4
l[1]=2,r[1]=5 S=2*(5-2-1)=4
所以最大面积为4
b.根据左右区间求出了每一行的最大面积后
可以知道 第二大矩形的面积=所有矩形中第二大的面积/最大面积的长或宽-1后相乘
具体实现:
对每一行中的列元素查找左右区间,要利用单调栈 具体讲解:单调栈
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int MAX=1e3;
int n,m;
int high[MAX+5][MAX+5],Stack[MAX+5],l[MAX+5],r[MAX+5];
char a[MAX+5][MAX+5];
int cnt;
int num[5*MAX*MAX+5];
bool flag[MAX+5][MAX+5];
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
high[i][0]=-1,high[i][m+1]=-1;
scanf("%s",a[i]+1);
for(int j=1;j<=m;j++){
if(a[i][j]=='0'){
high[i][j]=0;
continue;
}
if(i==0)
high[i][j]=a[i][j]-'0';
else
high[i][j]=high[i-1][j]+(a[i][j]-'0');
}
}
for(int i=0;i<n;i++){
int top=0;
Stack[top]=0;
for(int j=1;j<=m;j++){
while(high[i][Stack[top]]>=high[i][j]) top--;
l[j]=Stack[top];
Stack[++top]=j;
}
top=0;
Stack[top]=m+1;
for(int j=m;j>=1;j--){
while(high[i][Stack[top]]>=high[i][j]) top--;
r[j]=Stack[top];
Stack[++top]=j;
}
memset(flag,false,sizeof(flag));
for(int j=1;j<=m;j++){
int x=r[j]-l[j]-1,y=high[i][j];
if(!y) continue;
if(!flag[l[j]][r[j]]){ ///标记一行中出现过的左右区间,否则同一个矩形面积会多次计算
num[cnt++]=x*y;
num[cnt++]=(x-1)*y;
num[cnt++]=x*(y-1);
flag[l[j]][r[j]]=true;
}
}
}
sort(num,num+cnt);
printf("%d\n",num[cnt-2]);
return 0;
}
/*
1 7
2145133
0 0 2 3 0 5 5
2 8 5 5 8 8 8
*/
手机扫一扫
移动阅读更方便
你可能感兴趣的文章