给定01矩阵,求其中都为1的矩阵的最大面积。
想法很奇妙,先求每一行向上最多可以延伸多少,再对每一行对非0区域,用单调栈求区间最小值*区间长度,即为面积。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
using namespacestd;
const int maxn =2000 + 5;
int m,n;//m行n列
struct node{
int v,l,r;//v是[l,r]内的最小值
};
stack<node> stk;
int ans = 0;
node cnt[maxn][maxn];
node t;
void clear_stk()
{
while (!stk.empty()) {
t =stk.top();stk.pop();
ans =max(ans,t.v * (t.r - t.l +1));
if(!stk.empty()){
stk.top().r =t.r;
}
}
}
void solve()
{
for (int i =1;i <= m ; i ++) {
for (int j =1; j <= n; j ++) {
if(!cnt[i][j].v) {clear_stk();}
else {
if(stk.empty() ||cnt[i][j].v >=stk.top().v)
{
stk.push(cnt[i][j]);
}
else {
while (!stk.empty() &&cnt[i][j].v <stk.top().v) {
t =stk.top();stk.pop();
ans =max(ans,t.v * (t.r - t.l +1));
if(!stk.empty()){
stk.top().r =t.r;
}
cnt[i][j].l =t.l;
}
stk.push(cnt[i][j]);
}
}
}
clear_stk();
}
}
int main()
{
while (scanf("%d%d",&m,&n) != EOF) {
ans =0;
memset(cnt,0, sizeof(cnt));
for (int i =1; i <= m; i ++) {
for (int j =1; j <= n; j ++) {
scanf("%d",&cnt[i][j].v);
if(cnt[i][j].v)cnt[i][j].v =1 + cnt[i -1][j].v;
cnt[i][j].l =cnt[i][j].r = j;
}
}
solve();
printf("%d\n",ans);
}
return0;
}