牛客多校__Second Large Rectangle

鏈接:https://ac.nowcoder.com/acm/contest/882/H
來源:牛客網
 

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 262144K,其他語言524288K
64bit IO Format: %lld

題目描述

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

Containing all "1""1" means that the entries of the rectangle are all "1""1".
 

A rectangle can be defined as four integers x1,y1,x2,y2x1,y1,x2,y2 where 1≤x1≤x2≤N1≤x1≤x2≤N and 1≤y1≤y2≤M1≤y1≤y2≤M. Then, the rectangle is composed of all the cell (x, y) where x1≤x≤x2x1≤x≤x2 and y1≤y≤y2y1≤y≤y2. If all of the cell in the rectangle is "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 cijcij.

1≤N,M≤10001≤N,M≤1000
N×M≥2N×M≥2
cij∈"01"cij∈"01"

輸出描述:


 

Output one line containing an integer representing the answer. If there are less than 2 rectangles containning all "1""1", output "0""0".

示例1

輸入

複製

1 2
01

輸出

複製

0

示例2

輸入

複製

1 3
101

輸出

複製

1

題意:找出第二大的矩陣的面積(矩陣是0,1構成)

題解:普通做法n三方處理不了,所以先預處理出每個元素行上能擴展到多遠(O(n*n)),然後用單調棧求出每一列上的矩陣的最大,進行更新,同時還要將每個單調棧算出來的矩陣減一行更新一下答案,減一列更新下答案,用兩個變量維護一下最大和次大就行了

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
const ll mod = 1e9+7;


int A[1005][1005];
char Mat[1005][1005];
struct Node
{
    int num;
    int id;
}St[10005];

int main()
{
    //freopen("in.txt", "r", stdin);
    int n, m;
    while(~scanf("%d%d", &n, &m))
    {
        for(int i = 0; i < n; i++) scanf("%s", Mat[i]);
        for(int i = 1; i <= n; i++)
        {
            int pre = -1;
            int len = 0;
            for(int j = 1; j <= m; j++)
            {
                if(Mat[i-1][j-1] == '1')
                {
                    if(pre == -1) pre = j;
                    len++;
                }
                else
                {
                    A[i][j] = 0;
                    for(int k = pre; k < j && pre != -1; k++)
                    {
                        A[i][k] = len;
                        len--;
                    }
                    pre = -1;
                }
            }
            if(pre != -1)
            {
                for(int k = pre; k <= m; k++)
                {
                    A[i][k] = len;
                    len--;
                }
            }
        }
        int Max = -1, Max2 = -1;

        for(int j = 1; j <= m; j++)
        {
            int l = 0, r = 0;
            for(int i = 1; i <= n; i++)
            {
                int pre = i;
//                cout<<St[r-1].num<<" "<<A[i][j]<<" i"<<i<<endl;
                while(l < r)
                {
                    if(St[r-1].num >= A[i][j])
                    {
                        int x=(i-St[r-1].id)*St[r-1].num;
                        if(x>=Max){
                            Max2=Max;
                            Max=x;
                        }
                        else if(x>=Max2)Max2=x;

                        x=(i-St[r-1].id-1)*St[r-1].num;
                        if(x>=Max){
                            Max2=Max;
                            Max=x;
                        }
                        else if(x>=Max2)Max2=x;

                        x=(i-St[r-1].id)*(St[r-1].num-1);
                        if(x>=Max){
                            Max2=Max;
                            Max=x;
                        }
                        else if(x>=Max2)Max2=x;

                        pre = St[r-1].id;
                        r--;
                    }
                    else break;
                }
                St[r++] = {A[i][j], pre};
            }
            while(l<r){
                int x=(n-St[r-1].id+1)*St[r-1].num;
                if(x>=Max){
                    Max2=Max;
                    Max=x;
                }
                else if(x>=Max2)Max2=x;

                x=(n-St[r-1].id)*St[r-1].num;
                if(x>=Max){
                    Max2=Max;
                    Max=x;
                }
                else if(x>=Max2)Max2=x;

                x=(n-St[r-1].id+1)*(St[r-1].num-1);
                if(x>=Max){
                    Max2=Max;
                    Max=x;
                }
                else if(x>=Max2)Max2=x;

                r--;
            }
        }
        if(Max2 <= 0) printf("0\n");
        else printf("%d\n", Max2);
//        cout<<Max<<endl;
    }
    return 0;
}
/*
5 3
110
110
110
111
111
*/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章