• Second Large Rectangle【单调栈】


    Second Large Rectangle

    题目链接(点击)

    题目描述

    Given a N×MN imes MN×M binary matrix. Please output the size of second large rectangle containing all "1" exttt{"1"}"1".

    Containing all "1" exttt{"1"}"1" means that the entries of the rectangle are all "1" exttt{"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" exttt{"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 imes M geq 2N×M≥2
    cij∈"01"c_{ij} in exttt{"01"}cij​∈"01"

    输出描述:

    Output one line containing an integer representing the answer. If there are less than 2 rectangles containning all "1" exttt{"1"}"1", output "0" exttt{"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
    ",num[cnt-2]);
        return 0;
    }
    /*
    1 7
    2145133
    0 0 2 3 0 5 5
    2 8 5 5 8 8 8
    */
    
  • 相关阅读:
    [LeetCode] Contains Duplicate 包含重复值
    [LeetCode] 281. The Skyline Problem 天际线问题
    Qt resizeEvent 控件居中设置
    [LeetCode] 214. Shortest Palindrome 最短回文串
    Qt Creator Shortcuts 快捷键大全
    Qt SizePolicy 属性
    [LeetCode] 30. Substring with Concatenation of All Words 串联所有单词的子串
    [LeetCode] 213. House Robber II 打家劫舍之二
    [LeetCode] 212. Word Search II 词语搜索之二
    [LeetCode] 18. 4Sum 四数之和
  • 原文地址:https://www.cnblogs.com/ldu-xingjiahui/p/12407426.html
Copyright © 2020-2023  润新知