描述
在一片保护林中,护林员想要盖一座房子来居住,但他不能砍伐任何树木。
现在请你帮他计算:保护林中所能用来盖房子的矩形空地的最大面积。
关于输入
输入:
保护林用一个二维矩阵来表示,长宽都不超过20(即<=20)。
第一行是两个正整数m,n,表示矩阵有m行n列。
然后是m行,每行n个整数,用1代表树木,用0表示空地。
关于输出
输出:
一个正整数,表示保护林中能用来盖房子的最大矩形空地面积。
例子输入
4 5
0 1 0 1 1
0 1 0 0 1
0 0 0 0 0
0 1 1 0 1
例子输出
5
提示
子矩阵边长可以为1,也就是说:
0 0 0 0 0
依然是一个可以盖房子的子矩阵。
源码实现
#include<iostream>
#include<cstring>//memset头文件
using namespace std;
int max(int a, int b) {
return a > b ? a : b;
}//返回两数中较大的一个
int min(int a, int b) {
return a > b ? b : a;
}//返回两数中较小的一个
int main()
{
int m, n;
int a[21][21];
memset(a, 0, sizeof(a));
//采用memset赋初值,直接对内存进行操作,效率高
cin >> m >> n;
//键入m,n的值,表示矩阵有m行n列
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
cin >> a[i][j];
}
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (a[i][j] == 0) a[i][j] = a[i][j - 1] + 1;
else a[i][j] = 0;
}
}//作用:找出同一行中连续的空地
int ans = 0;
int width;
//遍历每一个位置,向上回溯的方式,求以该位置为左下角的树群的最大值
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (a[i][j] != 0) {//表示这一块有空地
width = a[i][j];//设置为当前的宽度
ans = max(ans, width * 1);
for (int k = i - 1; k >= 1; k--) {
if (a[k][j] == 0) {//如果搜到树,则说明不用再往上了
break;
}
else {//如果没有搜到树,更新宽度,继续进行
width = min(width, a[k][j]);
ans = max(ans, width * (i - k + 1));
}
}
}
}
}
cout << ans;
return 0;
}