您的位置:首页 > 职场人生

腾讯面试题(九度)——面积最大的全1子矩阵

2014-01-07 14:50 483 查看
题目地址:http://ac.jobdu.com/problem.php?pid=1497

题目描述:

在一个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. 动态规划——三个状态数组,分别保存当前点的高度up,左边界left,右边界right,max_value=max(max_value,up*(right-left+1);

#include &l
4000
t;iostream>
using namespace std;
#include <algorithm>

#define N 1000

bool data

;
int up

;
int l_flag

;
int r_flag

;

int main()
{
int m,n;
int max_1;
int l_num,r_num;
while(cin>>m>>n)
{
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
cin>>data[i][j];
max_1=0;
for(int i=0;i<m;i++)
{
l_num=-1;
r_num=n;
for(int j=0;j<n;j++)
{
if(!data[i][j])
{
up[i][j]=0;
l_flag[i][j]=0;
l_num=j;
}
else
{
if(i==0)
{
up[i][j]=1;
l_flag[i][j]=l_num+1;
}
else
{
up[i][j]=up[i-1][j]+1;
l_flag[i][j]=max(l_num+1,l_flag[i-1][j]);
}
}
}
for(int j=n-1;j>=0;j--)
{
if(!data[i][j])
{
r_flag[i][j]=n;
r_num=j;
}
else
{
if(i==0)
r_flag[i][j]=r_num-1;
else
r_flag[i][j]=min(r_num-1,r_flag[i-1][j]);
}
max_1=max(max_1,up[i][j]*(r_flag[i][j]-l_flag[i][j]+1));
}
}
cout<<max_1<<endl;
}
return 0;
}

2.向右得到每个点左边连续1的个数,如 0 1 0 1 1 0 -> 0 1 0 1 2 0。然后算每列的最大1矩阵,例如:

某列 为 1 2 3 3 4 2 0 ,得到最大1矩阵为2*5=10,具体方法为对每个元素分别向上(左)向下(右)查询连续大于等于自己的元素个数,然后相乘

此方法在九都测试超时,但是结果是对的。

#include <iostream>
using namespace std;
#include <algorithm>

bool data[1000][1000];
int flag[1000][1000];

int main()
{
int m,n;
int max_1,value,depth;
int x;
while(cin>>m>>n)
{
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{
cin>>data[i][j];
if(data[i][j])
{
if(j==0)
flag[i][j]=1;
else
flag[i][j]=flag[i][j-1]+1;
}
else
flag[i][j]=0;
}
max_1=0;
for(int j=0;j<n;j++)
{
for(int i=0;i<m;i++)
{
if(flag[i][j]==0)
continue;
depth=1;
value=flag[i][j];
x=i;
while(x>0)
{
if(flag[--x][j]>=value)
depth+=1;
else
break;
}
x=i;
while(x<m-1)
{
if(flag[++x][j]>=value)
depth+=1;
else
break;
}
max_1=max(max_1,depth*value);
}
}
cout<<max_1<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息