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.
The input contains multiple test cases. Each test case begins with mand n (1 ≤ m, n ≤ 2000) on line. Then come the elements of a (0,1)-matrix in row-major order on m lines each with n numbers. The input ends once EOF is met.
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.
2 2 0 0 0 0 4 4 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0Sample Output
0
4
如果對每個值都水平豎直方向找的話肯定會超時的
所以可以想到 把1改成它的高度 這樣光水平方向找就可以了
0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0改成
0 0 0 0
0 1 1 0
0 2 2 0
0 0 0 0
接下來又和
poj2796 feel good 單調棧 前後延伸
很像了 這次是隻要左右兩邊>=它就可以延伸
只不過這次只需要區間長度 所以可以讓對應的j座標入棧
構造單增棧 最後一列置爲-1保證元素全彈出
如果棧空 說明他是目前最小的 之前的都比他大 所以寬度就等於j
否則寬度爲j-s.top()-1 s.top()是前面比他小的元素的座標 因爲座標從0開始所以減1
#include <iostream>
#include<stack>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=2010;
int a[maxn][maxn];
int b[maxn][maxn];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=-1)
{
memset(b,0,sizeof(b));
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
scanf("%d",&a[i][j]);
}
for(int i=0;i<n;i++) //另一個矩陣
{
for(int j=0;j<m;j++)
{
if(a[i][j]==0)b[i][j]=0;
else
{
if(i==0)b[i][j]=a[i][j];
else b[i][j]=a[i][j]+b[i-1][j];
}
}
}
int j;
for(int i=0;i<n;i++)
b[i][m]=-1;
int mmax=-999;
for(int i=0;i<n;i++)
{
stack<int>s;
for(int j=0;j<=m;j++)
{
if(s.empty()||b[i][j]>b[i][s.top()])
{
s.push(j);
}
else
{
int tmp=s.top();
s.pop();
int w;
if(s.empty())
{
w=j;
}
else w=j-s.top()-1;
int ans=b[i][tmp]*w;
mmax=max(ans,mmax);
j--; //元素成功入棧時纔去下一個j
}
}
}
printf("%d\n",mmax);
}
return 0;
}