您的位置:首页 > 其它

[Jobdu] 题目1497:面积最大的全1子矩阵

2014-08-04 17:14 281 查看
题目描述:
在一个M * N的矩阵中,所有的元素只有0和1,从这个矩阵中找出一个面积最大的全1子矩阵,所谓最大是指元素1的个数最多。

输入:
输入可能包含多个测试样例。
对于每个测试案例,输入的第一行是两个整数m、n(1<=m、n<=1000):代表将要输入的矩阵的大小。
矩阵共有m行,每行有n个整数,分别是0或1,相邻两数之间严格用一个空格隔开。

输出:
对应每个测试案例,输出矩阵中面积最大的全1子矩阵的元素个数。

样例输入:
2 2
0 0
0 0
4 4
0 0 0 0
0 1 1 0
0 1 1 0
0 0 0 0

样例输出:
0
4


  可以将上述问题转化为求直方图中最大的矩形的面积,将原矩阵中的每一行视为一个直方图,对于每一行中的每一列的值为该行之上的1的个数,下面分别利用直方图的算法来求解每一行中的最大值,然后求出全局最大值。代码如下:

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

int m, n;
int a[1000][1000];
int b[2][1001];
int f = 0;

int getMax() {
stack<int> s;
b[f]
= 0;
int max = 0, tmp;
for (int i = 0; i <= n; ++i) {
if (s.empty() || b[f][s.top()] < b[f][i]) {
s.push(i);
} else {
int idx = s.top();
s.pop();
tmp = b[f][idx] * (s.empty() ? i : i - s.top() - 1);
max = (max > tmp) ? max : tmp;
--i;
}
}
return max;
}

void getRes() {
int max = getMax(), tmp;
++f; f %= 2;
for (int i = 1; i < m; ++i) {
for (int j = 0; j < n; ++j) {
b[f][j] = (a[i][j] == 0) ? 0 : b[(f+1)%2][j] + 1;
}
tmp = getMax();
++f; f %= 2;
max = (max > tmp) ? max : tmp;
}
cout << max << endl;
}

int main() {
//freopen("1497.in", "r", stdin);
while (cin >> m >> n) {
f = 0;
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
cin >> a[i][j];
if (i == 0)
b[0][j] = a[0][j];
}
}
getRes();
}
return 0;
}

/**************************************************************
Problem: 1497
User: hupo250
Language: C++
Result: Accepted
Time:800 ms
Memory:5432 kb
****************************************************************/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: