zoukankan      html  css  js  c++  java
  • 牛客网(暑假集训#2)H

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

    A rectangle can be defined as four integers x1,y1,x2,ywhere 1x1x2and 1≤y1≤y2≤M. Then, the rectangle is composed of all the cell (x, y) where x1xxand y1yy2. If all of the cell in the rectangle is "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.

    Input

    The first line of input contains two space-separated integers N and M.
    Following N lines each contains M characters cij.

    1N,M1000

    N×M2

    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
    ",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
    ",m2);
    45     return 0;
    46 }
    View Code

    Appendix

    补题网址

    我思故我在
  • 相关阅读:
    应用的可被点击与不可被点击
    去掉NavigationBar底部的黑线
    iOS 设计模式之工厂模式
    GCD的用法
    ARC以及MRC中setter方法
    alpha,hidden,opaque的一些认识
    self进行weak化
    iOS之获取当前时间日期并按固定格式显示
    iOS之AVPlayer的简单应用
    Xcode快捷键、小技巧与xib圆角设置
  • 原文地址:https://www.cnblogs.com/pisceskkk/p/11229105.html
Copyright © 2011-2022 走看看