遍历每个点,用二分向上下左右扩展找到最大能到的没被虫蛀的点
再遍历每个点,先让他再上下方向全满,然后用二分左右找看有没有可以接上的,统计一次答案
然后让他左右方向拉满,用二分上下找看有没有接上的,统计一次答案
但是只有60分
#include <iostream>
#include <algorithm>
using namespace std;
const int N=305;
int a[N][N],s[N][N],v[N][N];
int U[N][N],D[N][N],L[N][N],R[N][N];
int querys(int x1,int y1,int x2,int y2) {
return s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1];
}
int queryv(int x1,int y1,int x2,int y2) {
return v[x2][y2]-v[x2][y1-1]-v[x1-1][y2]+v[x1-1][y1-1];
}
int main() {
int n,m;
scanf("%d %d",&n,&m);
for (int i=1;i<=n;i++) {
for (int j=1;j<=m;j++) {
scanf("%d",&a[i][j]);
s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
v[i][j]=v[i-1][j]+v[i][j-1]-v[i-1][j-1]+(a[i][j]==0?1:0);
}
}
for (int i=1;i<=n;i++) {
for (int j=1;j<=m;j++) {
int l=1,r=i-1;
U[i][j]=D[i][j]=i;
while (l<=r) {
int mid=(l+r)>>1;
if (queryv(mid,j,i,j)==0) {
U[i][j]=min(U[i][j],mid);
r=mid-1;
}else {
l=mid+1;
}
}
l=i+1,r=n;
while (l<=r) {
int mid=(l+r)>>1;
if (queryv(i,j,mid,j)==0) {
D[i][j]=max(D[i][j],mid);
l=mid+1;
}else {
r=mid-1;
}
}
L[i][j]=R[i][j]=j;
l=1,r=j-1;
while (l<=r) {
int mid=(l+r)>>1;
if (queryv(i,mid,i,j)==0) {
L[i][j]=min(L[i][j],mid);
r=mid-1;
}else {
l=mid+1;
}
}
l=j+1,r=m;
while (l<=r) {
int mid=(l+r)>>1;
if (queryv(i,j,i,mid)==0) {
R[i][j]=max(R[i][j],mid);
l=mid+1;
}else {
r=mid-1;
}
}
}
}
int ans=0;
for (int i=1;i<=n;i++) {
for (int j=1;j<=m;j++) {
if (a[i][j]==0) continue;
int l=1,r=j-1,ansl=j,ansr=j,ansu=i,ansd=i;
while (l<=r) {
int mid=(l+r)>>1;
if (queryv(U[i][j],mid,D[i][j],j)==0) {
ansl=min(ansl,mid);
r=mid-1;
}else {
l=mid+1;
}
}
l=j+1,r=m;
while (l<=r) {
int mid=(l+r)>>1;
if (queryv(U[i][j],j,D[i][j],mid)==0) {
ansr=max(ansr,mid);
l=mid+1;
}else {
r=mid-1;
}
}
ans=max(ans,querys(U[i][j],ansl,D[i][j],ansr));
l=1,r=i-1;
while (l<=r) {
int mid=(l+r)>>1;
if (queryv(mid,L[i][j],i,R[i][j])==0) {
ansu=min(ansu,mid);
r=mid-1;
}else {
l=mid+1;
}
}
l=i+1,r=n;
while (l<=r) {
int mid=(l+r)>>1;
if (queryv(i,L[i][j],mid,R[i][j])==0) {
ansd=max(ansd,mid);
l=mid+1;
}else {
r=mid-1;
}
}
ans=max(ans,querys(ansu,L[i][j],ansd,R[i][j]));
}
}
printf("%d",ans);
return 0;
}