Second Large Rectangle(单调栈)

 H-Second Large Rectangle_2019⽜客暑期多校训练营(第⼆场)
https://ac.nowcoder.com/acm/contest/882/H 1/1
 Second    Large    Rectangle
时间限制:C/C++    1秒,其他语言2秒 空间限制:C/C++    262144K,其他语言524288K 64bit    IO    Format:    %lld
题目描述    
Given    a    N*M   binary    matrix.    Please    output    the    size    of    second    large    rectangle    containing    all    “1”.
输入描述:

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 one line containing an integer representing the answer. If there are less than 2 rectangles containning all "1", output 0

示例1

输入

1 2

01

输出

0

示例2

输入

1 3

101

输出

1

这个题是求满足包含的数全为“1”的第二大矩形的面积,这个题根据题意可知长方形的面积就是其中包含1的个数,所以对于每一列我们先求一个连续的前缀和,表示矩形的长,接下来找矩形的左右界(即宽)即可,找左右界的过程就用到了单调栈,只要当前元素旁边的长度大于当前长度,那宽度就可以+1(相当于把矩形拓宽)

完整代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
char ch[1010][1010];
int val[1010][1010];
int max1=0,max2=0,n,m;
void f(int x)
{
    if(x>max1)
    {
        max2=max1;
        max1=x;
    }
    else if(x>max2)
    {
        max2=x;
    }
}
signed main()
{
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",ch[i]+1);
        for(int j=1;j<=m;j++)
        {
            if(ch[i][j]=='1')
            {
                val[i][j]=val[i-1][j]+1;
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
        stack<int> t;
        val[i][0]=-2;
        val[i][m+1]=-1;
        t.push(0);
        for(int j=1;j<=m+1;j++)
        {
            while(val[i][t.top()]>val[i][j])
            {
                int k=t.top();
                t.pop();
                int x=j-1-t.top(),y=val[i][k];
                f(x*y);
                f(max(x*(y-1),(x-1)*y));
            }
            t.push(j);
        }
        t.pop();
    }
    printf("%lld",max2);
    return 0;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值