Given a m-by-n (0,1)-matrix, of all its submatrices of all 1’s which is the largest? By largest we mean that the submatrix has the most elements.
Input
The input contains multiple test cases. Each test case begins with m and n (1 ≤ m, n ≤ 2000) on line. Then come the elements of a (0,1)-matrix in row-major order on mlines each with n numbers. The input ends once EOF is met.
Output
For each test case, output one line containing the number of elements of the largest submatrix of all 1’s. If the given matrix is of all 0’s, output 0.
Sample Input
2 2 0 0 0 0 4 4 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0
Sample Output
0 4
題意:
找最大的為1的子矩陣,
一開始的錯誤程式碼:H是表示他的連續高度,L和R是左邊第一個比他小的座標和右邊比他小的座標,這個過程都是單調棧維護的,
然後暴力列舉最大的點,但是這樣有錯誤,就是L到R這個區間內H的值不一定是相同的
錯誤程式碼:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<vector>
#include<cmath>
const int maxn=1e5+5;
typedef long long ll;
using namespace std;
int n,m;
int Map[2005][2005];
int H[2005][2005];
int L[2005][2005];
int R[2005][2005];
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
while(cin>>n>>m)
{
for(int t=1;t<=n;t++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&Map[t][j]);
}
}
for(int t=1;t<=n;t++)
{
for(int j=1;j<=m;j++)
{
if(Map[t][j]==1)
{
H[t][j]=1;
}
else
{
H[t][j]=0;
}
}
}
memset(L,0,sizeof(L));
for(int t=1;t<=n;t++)
{
for(int j=1;j<=m;j++)
{
R[t][j]=m+1;
}
}
for(int t=2;t<=n;t++)
{
for(int j=1;j<=m;j++)
{
if(H[t-1][j]!=0&&H[t][j]==1)
{
H[t][j]=H[t-1][j]+1;
}
}
}
for(int t=1;t<=n;t++)
{
stack<int>S1;
for(int j=1;j<=m;j++)
{
while(S1.size() && Map[t][S1.top()]>=Map[t][j]) S1.pop();
if(S1.empty()) L[t][j]= 0;
else L[t][j] = S1.top();
S1.push(j);
}
}
for(int t=1;t<=n;t++)
{
stack<int>S1;
for(int j=m;j>=1;j--)
{
while(S1.size() && Map[t][S1.top()]>=Map[t][j]) S1.pop();
if(S1.empty()) R[t][j]= m+1;
else R[t][j] = S1.top();
S1.push(j);
}
}
int manxx=0;
for(int t=1;t<=n;t++)
{
for(int j=1;j<=m;j++)
{
if(H[t][R[t][j]-1]==H[t][L[t][j]+1])
manxx=max(manxx,H[t][j]*(R[t][j]-L[t][j]-1));
}
}
cout<<manxx<<endl;
}
return 0;
}
AC程式碼:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<cmath>
const int maxn=2e5+5;
typedef long long ll;
using namespace std;
int H[2005];
int a[2005];
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int n,m,x,top,tmp,maxnxx;
stack<int>S1;
while(cin>>n>>m)
{
maxnxx=0;
memset(H,0,sizeof(H));
for(int t=0;t<n;t++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&x);
if(x==1) H[j]=H[j]+1;
else H[j]=0;
a[j]=H[j];
}
a[m+1]=-1;
for(int j=1;j<=m+1;j++)
{
if(S1.empty()||a[j]>=a[S1.top()])
{
S1.push(j);
}
else
{
while(!S1.empty()&&a[j]<a[S1.top()])
{
top=S1.top();
S1.pop();
tmp=(j-top)*a[top];
if(tmp>maxnxx) maxnxx=tmp;
}
S1.push(top);
a[top]=a[j];
}
}
}
cout<<maxnxx<<endl;
}
return 0;
}