POJ 3494 Largest Submatrix of All 1’s(单调栈)

简介: POJ 3494 Largest Submatrix of All 1’s(单调栈)

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 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 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

首先找每个点向上的最大高度,然后再对每个点向左扩展,再向右扩展。
找每个点向左向右方向第一个比它小的位置是一个单调减栈。

#include<iostream>
#include<cstdio>
#include<stack>
#include <cstring>
#include<algorithm>
using namespace std;

int m,n;
int a[2005][2005];
int u[2005][2005];
int l[2005][2005],r[2005][2005];

int main()
{
   
    while(scanf("%d%d",&m,&n)!=EOF){
   
        for(int i=1;i<=m;i++){
   
            for(int j=1;j<=n;j++){
   
                scanf("%d",&a[i][j]);
            }
        }
        stack<pair<int,int> > s;
        memset(u,0,sizeof(u));
        for(int i=1;i<=m;i++){
   //求出每个点向上连续的最大长度 
            for(int j=1;j<=n;j++){
   
                if(a[i][j]==0) u[i][j]=0;
                else u[i][j]=u[i-1][j]+1;
            }
        }
        for(int i=1;i<=m;i++){
   
            while(!s.empty()) s.pop();
            for(int j=1;j<=n;j++){
   
                while(!s.empty()&&s.top().first>=u[i][j]){
   //找左边第一个比它小的位置 
                    s.pop();
                }
                if(s.empty()) l[i][j]=1;
                else l[i][j]=s.top().second+1;
                s.push(pair<int,int>(u[i][j],j));
            }
        }

            for(int i=1;i<=m;i++){
   
                while(!s.empty()) s.pop();
                for(int j=n;j>=1;j--){
   
                    while(!s.empty()&&s.top().first>=u[i][j]){
   
                    s.pop();
                    }
                    if(s.empty()) r[i][j]=m;
                    else r[i][j]=s.top().second-1;
                    s.push(pair<int,int>(u[i][j],j));
             }
            }

            int res=0;
            for(int i=1;i<=m;i++){
   
                for(int j=1;j<=n;j++){
   
                    res=max(res,u[i][j]*(r[i][j]-l[i][j]+1));
                }
            }
        printf("%d\n",res);
    }
    return 0;
}
相关文章
|
5天前
|
算法 C语言 C++
【practise】栈的压入和弹出序列
【practise】栈的压入和弹出序列
|
3天前
栈的几个经典应用,真的绝了
文章总结了栈的几个经典应用场景,包括使用两个栈来实现队列的功能以及利用栈进行对称匹配,并通过LeetCode上的题目示例展示了栈在实际问题中的应用。
栈的几个经典应用,真的绝了
|
4天前
|
存储 网络协议 Linux
用户态协议栈06-TCP三次握手
用户态协议栈06-TCP三次握手
|
4天前
|
存储
全局变量和局部变量在堆和栈的区别
全局变量和局部变量在堆和栈的区别
11 0
|
5天前
|
存储 人工智能 运维
高质量存储力发展问题之浪潮信息发布的大模型智算软件栈的定义如何解决
高质量存储力发展问题之浪潮信息发布的大模型智算软件栈的定义如何解决
8 0
|
5天前
|
设计模式 算法 C语言
【CPP】栈、双端队列、队列、优先级队列与反向迭代器
【CPP】栈、双端队列、队列、优先级队列与反向迭代器
|
5天前
|
存储 算法 C++
【CPP】栈简介及简化模拟实现
【CPP】栈简介及简化模拟实现
|
6天前
【数据结构】用栈实现队列
【数据结构】用栈实现队列
|
6天前
【数据结构】用队列实现栈
【数据结构】用队列实现栈
|
6天前
【数据结构】栈
【数据结构】栈