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
Represents the first obstacle encountered by the point (i,j) walking to the left,
Indicates the first obstacle encountered when walking to the right.
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.
represents the first obstacle that my (i, j) line encounters to the left,
Indicates the first obstacle to the right, so my final answer is (
1)
.
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;
}