Second Large Rectangle
题目链接
题意:给定一个矩阵,只包含0 和 1,问全是1的次最大子矩阵的大小。
思路:利用vector 存矩阵大小。。。 单调栈求 最大全是1的子矩阵,在此基础上每一次再多push_back (Height - 1) * Width 和 Height * (Width - 1),最后排序取次最大即可,。
Code:
#include<bits/stdc++.h>
#define debug(x) cout << "[" << #x <<": " << (x) <<"]"<< endl
#define pii pair<int,int>
#define clr(a,b) memset((a),b,sizeof(a))
#define rep(i,a,b) for(int i = a;i < b;i ++)
#define pb push_back
#define MP make_pair
#define LL long long
#define ull unsigned LL
#define ls i << 1
#define rs (i << 1) + 1
#define INT(t) int t; scanf("%d",&t)
using namespace std;
const int maxn = 1010;
int H[maxn][maxn];
char mp[maxn][maxn];
int n,m;
stack<int>St;
int solve(){
vector<int>ans;
for(int i = 1;i <= n;++ i){
while(!St.empty()) St.pop();
H[i][m + 1] = -1;
int Hei,Wid,top;
for(int j = 1;j <= m + 1;++ j){
if(St.empty() || H[i][St.top()] <= H[i][j]){
St.push(j);
continue;
}
while(!St.empty() && (H[i][St.top()] > H[i][j])){
top = St.top();
Hei = H[i][top];
Wid = j - St.top();
St.pop();
if(Hei && Wid){
ans.push_back(Hei * Wid);
if(Hei - 1)
ans.push_back((Hei - 1) * Wid);
if(Wid - 1)
ans.push_back(Hei * (Wid - 1));
}
}
H[i][top] = H[i][j]; /// 注意要更新
St.push(top); /// 向左扩展,如后面样例
}
}
if(ans.size() <= 1) return 0;
sort(ans.begin(),ans.end());
return ans[ans.size() - 2];
}
int main() {
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;++ i)
scanf("%s",mp[i] + 1);
for(int i = 1;i <= n;++ i){
for(int j = 1;j <= m;++ j)
if(mp[i][j] == '1') H[i][j] = H[i - 1][j] + 1;
}
printf("%d\n",solve());
return 0;
}
//2 2
//10
//11