Maximum all-zero rectangle (dangling method)

foreword

Today I opened a question, luogu1169 chessboard making, and found that I can't. I asked my classmates and told me that it was a popular group question. I felt that I was in vain to improve the players. . .
Then learn a wave of hanging lines.
by l [ i ] [ j ] Represents the first obstacle encountered by the point (i,j) walking to the left, r [ i ] [ j ] Indicates the first obstacle encountered when walking to the right.
h [ i ] [ j ] The so-called hanging line means that you can walk up a few steps at most. Then there is an obvious conclusion. The final answer must be obtained by extending a hanging line to the left and right sides. Otherwise, you can take another step up.
L [ i ] [ j ] represents the first obstacle that my (i, j) line encounters to the left, R [ i ] [ j ] Indicates the first obstacle to the right, so my final answer is ( R [ i ] [ j ] L [ i ] [ j ] 1) h [ i ] [ j ] .
It may be difficult to explain the method, so let’s go directly to the code, it is very clear

#include<cstdio>
#include<algorithm>
#include<cctype>
#include<cstring>
#include<iostream>
#define LL long long
#define INF (2139062143)
#define N (2005)
using namespace std;
int n,m,x,ans1,t,ans;
int map[N][N],l[N][N],r[N][N],L[N][N],R[N][N],a[N][N],h[N][N];
template <typename T> void read(T&t) {
    t=0;
    bool fl=true;
    char p=getchar();
    while (!isdigit(p)) {
        if (p=='-') fl=false;
        p=getchar();
    }
    do {
        (t*=10)+=p-48;p=getchar();
    }while (isdigit(p));
    if (!fl) t=-t;
}
int main(){
    read(n),read(m);
    for (int i=1;i<=n;i++){
        for (int j=1;j<=m;j++){
            read(x);
            a[i][j]=x^((i+j)&1);
        }
    }
    for (int i=1;i<=n;i++){
        t=0;
        for (int j=1;j<=m;j++){
            if (a[i][j]){
                l[i][j]=t;
            }   
            else t=j,L[i][j]=0;
        }
        t=m+1;
        for (int j=m;j>1;j--){
            if (a[i][j]){
                r[i][j]=t;      
            }
            else t=j,R[i][j]=m+1;
        }
    } 
    for (int i=1;i<=m;i++) L[0][i]=0,R[0][i]=m+1;
    for (int i=1;i<=n;i++){
        for (int j=1;j<=m;j++){
            if (a[i][j]){
                h[i][j]=h[i-1][j]+1;
                L[i][j]=max(L[i-1][j],l[i][j]);
                R[i][j]=min(R[i-1][j],r[i][j]);
                ans=max(ans,(R[i][j]-L[i][j]-1)*h[i][j]);
                int tt=min(R[i][j]-L[i][j]-1,h[i][j]);
                ans1=max(ans1,tt*tt);
            }
            else h[i][j]=0;
        }
    }
    memset(l,0,sizeof(l));
    memset(r,0,sizeof(r));
    memset(L,0,sizeof(L));
    memset(R,0,sizeof(R));
    memset(h,0,sizeof(h)); 
    for (int i=1;i<=n;i++){
        t=0;
        for (int j=1;j<=m;j++){
            if (!a[i][j]){
                l[i][j]=t;
            }   
            else t=j,L[i][j]=0;
        }
        t=m+1;
        for (int j=m;j>1;j--){
            if (!a[i][j]){
                r[i][j]=t;      
            }
            else t=j,R[i][j]=m+1;
        }
    } 
    for (int i=1;i<=m;i++) L[0][i]=0,R[0][i]=m+1;
    for (int i=1;i<=n;i++){
        for (int j=1;j<=m;j++){
            if (!a[i][j]){
                h[i][j]=h[i-1][j]+1;
                L[i][j]=max(L[i-1][j],l[i][j]);
                R[i][j]=min(R[i-1][j],r[i][j]);
                ans=max(ans,(R[i][j]-L[i][j]-1)*h[i][j]);
                int tt=min(R[i][j]-L[i][j]-1,h[i][j]);
                ans1=max(ans1,tt*tt);
            }
            else h[i][j]=0;
        }
    }
    printf("%d\n%d",ans1,ans);
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325479950&siteId=291194637