题目链接:https://ac.nowcoder.com/acm/contest/882/H
最大全零子矩阵扩展题
先一遍单调栈记录某一个最大的矩阵
再一遍单调栈,如果当前最大的矩阵长宽为h,len,且坐标与记录的最大矩阵的坐标不同,ans=max(h*len,ans)
不然就只更新h-1和len-1的情况
#include<bits/stdc++.h>
#define maxl 1010
using namespace std;
int n,m,top,mx,mx1,my1,mx2,my2,secmx;
int s[maxl],h[maxl],l[maxl],r[maxl];
int a[maxl][maxl];
char ch[maxl];
inline void prework()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%s",ch+1);
for(int j=1;j<=m;j++)
a[i][j]=ch[j]-'0';
}
}
inline void solve1()
{
mx=0;int tmp;
for(int i=1;i<=m;i++)
h[i]=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
if(a[i][j]==1)
h[j]++;
else
h[j]=0;
top=0;
for(int j=1;j<=m;j++)
{
while(top>0 && h[s[top]]>h[j])
r[s[top]]=j-1,--top;
l[j]=s[top]+1;
s[++top]=j;
}
while(top>0)
r[s[top]]=m,--top;
for(int j=1;j<=m;j++)
if(h[j])
{
tmp=h[j]*(r[j]-l[j]+1);
if(tmp>mx)
{
mx=tmp;
mx1=i-h[j]+1;my1=l[j];
mx2=i;my2=r[j];
}
}
}
}
inline void solve2()
{
secmx=0;int tmp,tx1,tx2,ty1,ty2;
for(int i=1;i<=m;i++)
h[i]=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
if(a[i][j]==1)
h[j]++;
else
h[j]=0;
top=0;
for(int j=1;j<=m;j++)
{
while(top>0 && h[s[top]]>h[j])
r[s[top]]=j-1,--top;
l[j]=s[top]+1;
s[++top]=j;
}
while(top>0)
r[s[top]]=m,--top;
for(int j=1;j<=m;j++)
if(h[j])
{
tx1=i-h[j]+1;ty1=l[j];
tx2=i;ty2=r[j];
tmp=h[j]*(r[j]-l[j]+1);
if(mx1!=tx1 || my1!=ty1 || mx2!=tx2 || my2!=ty2)
secmx=max(tmp,secmx);
secmx=max(secmx,(h[j]-1)*(r[j]-l[j]+1));
secmx=max(secmx,h[j]*(r[j]-l[j]));
}
}
}
inline void mainwork()
{
solve1();
solve2();
}
inline void print()
{
printf("%d\n",secmx);
}
int main()
{
prework();
mainwork();
print();
return 0;
}