鏈接:https://ac.nowcoder.com/acm/contest/882/H
來源:牛客網
時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 262144K,其他語言524288K
64bit IO Format: %lld
題目描述
Given a N×MN×M binary matrix. Please output the size of second large rectangle containing all "1""1".
Containing all "1""1" means that the entries of the rectangle are all "1""1".
A rectangle can be defined as four integers x1,y1,x2,y2x1,y1,x2,y2 where 1≤x1≤x2≤N1≤x1≤x2≤N and 1≤y1≤y2≤M1≤y1≤y2≤M. Then, the rectangle is composed of all the cell (x, y) where x1≤x≤x2x1≤x≤x2 and y1≤y≤y2y1≤y≤y2. If all of the cell in the rectangle is "1""1", this is a valid rectangle.
Please find out the size of the second largest rectangle, two rectangles are different if exists a cell belonged to one of them but not belonged to the other.
輸入描述:
The first line of input contains two space-separated integers N and M.
Following N lines each contains M characters cijcij.
1≤N,M≤10001≤N,M≤1000
N×M≥2N×M≥2
cij∈"01"cij∈"01"
輸出描述:
Output one line containing an integer representing the answer. If there are less than 2 rectangles containning all "1""1", output "0""0".
示例1
輸入
1 2 01
輸出
0
示例2
輸入
1 3 101
輸出
1
題意:找出第二大的矩陣的面積(矩陣是0,1構成)
題解:普通做法n三方處理不了,所以先預處理出每個元素行上能擴展到多遠(O(n*n)),然後用單調棧求出每一列上的矩陣的最大,進行更新,同時還要將每個單調棧算出來的矩陣減一行更新一下答案,減一列更新下答案,用兩個變量維護一下最大和次大就行了
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
const ll mod = 1e9+7;
int A[1005][1005];
char Mat[1005][1005];
struct Node
{
int num;
int id;
}St[10005];
int main()
{
//freopen("in.txt", "r", stdin);
int n, m;
while(~scanf("%d%d", &n, &m))
{
for(int i = 0; i < n; i++) scanf("%s", Mat[i]);
for(int i = 1; i <= n; i++)
{
int pre = -1;
int len = 0;
for(int j = 1; j <= m; j++)
{
if(Mat[i-1][j-1] == '1')
{
if(pre == -1) pre = j;
len++;
}
else
{
A[i][j] = 0;
for(int k = pre; k < j && pre != -1; k++)
{
A[i][k] = len;
len--;
}
pre = -1;
}
}
if(pre != -1)
{
for(int k = pre; k <= m; k++)
{
A[i][k] = len;
len--;
}
}
}
int Max = -1, Max2 = -1;
for(int j = 1; j <= m; j++)
{
int l = 0, r = 0;
for(int i = 1; i <= n; i++)
{
int pre = i;
// cout<<St[r-1].num<<" "<<A[i][j]<<" i"<<i<<endl;
while(l < r)
{
if(St[r-1].num >= A[i][j])
{
int x=(i-St[r-1].id)*St[r-1].num;
if(x>=Max){
Max2=Max;
Max=x;
}
else if(x>=Max2)Max2=x;
x=(i-St[r-1].id-1)*St[r-1].num;
if(x>=Max){
Max2=Max;
Max=x;
}
else if(x>=Max2)Max2=x;
x=(i-St[r-1].id)*(St[r-1].num-1);
if(x>=Max){
Max2=Max;
Max=x;
}
else if(x>=Max2)Max2=x;
pre = St[r-1].id;
r--;
}
else break;
}
St[r++] = {A[i][j], pre};
}
while(l<r){
int x=(n-St[r-1].id+1)*St[r-1].num;
if(x>=Max){
Max2=Max;
Max=x;
}
else if(x>=Max2)Max2=x;
x=(n-St[r-1].id)*St[r-1].num;
if(x>=Max){
Max2=Max;
Max=x;
}
else if(x>=Max2)Max2=x;
x=(n-St[r-1].id+1)*(St[r-1].num-1);
if(x>=Max){
Max2=Max;
Max=x;
}
else if(x>=Max2)Max2=x;
r--;
}
}
if(Max2 <= 0) printf("0\n");
else printf("%d\n", Max2);
// cout<<Max<<endl;
}
return 0;
}
/*
5 3
110
110
110
111
111
*/