Largest Submatrix of All 1’s

来源:互联网 发布:mac os 离线升级 编辑:程序博客网 时间:2024/05/19 18:37

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 mand n (1 ≤ mn ≤ 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.

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 20 00 04 40 0 0 00 1 1 00 1 1 00 0 0 0
Sample Output
0

4

如果对每个值都水平竖直方向找的话肯定会超时的

所以可以想到 把1改成它的高度 这样光水平方向找就可以了

0 0 0 00 1 1 00 1 1 00 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;
}

原创粉丝点击