1158 全是1的最大子矩阵
- 1 秒
- 131,072 KB
- 40 分
- 4 级题
给出1个M*N的矩阵M1,里面的元素只有0或1,找出M1的一个子矩阵M2,M2中的元素只有1,并且M2的面积是最大的。输出M2的面积。
收起
输入
第1行:2个数m,n中间用空格分隔(2 <= m,n <= 500) 第2 - N + 1行:每行m个数,中间用空格分隔,均为0或1。
输出
输出最大全是1的子矩阵的面积。
输入样例
3 3 1 1 0 1 1 1 0 1 1
输出样例
4
题解:以前做过最大子矩阵和,这两类题目类似;
先枚举一个上界一个下界,将某几行进行压缩,然后找到最长的,全为1的长度,其乘以 |行差| 等于面积。
#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<bitset>
#include<iomanip>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define eps (1e-8)
#define MAX 0x3f3f3f3f
#define u_max 1844674407370955161
#define l_max 9223372036854775807
#define i_max 2147483647
#define re register
#define pushup() tree[rt]=(tree[rt<<1],tree[rt<<1|1]);
#define nth(k,n) nth_element(a,a+k,a+n); // 将 第K大的放在k位
#define ko() for(int i=2;i<=n;i++) s=(s+k)%i // 约瑟夫
#define ok() v.erase(unique(v.begin(),v.end()),v.end()) // 排序,离散化
#define Catalan C(2n,n)-C(2n,n-1) (1,2,5,14,42,132,429...) // 卡特兰数
using namespace std;
inline int read(){
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' & c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
typedef long long ll;
const double pi = atan(1.)*4.;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fLL;
const int M=63;
const int N=5e6+5;
int n,m,a[505][505];
int b[505];
int fun(int k){
int num=0;
int p1=1;
while(p1<=m){
int j=p1;
while(b[j]==k)
j++;
num=max(num,j-p1);
p1=j+1;
}
return num;
}
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
int ans=0;
for(int i=1;i<=n;i++){ // 上界 i 下界 j
memset(b,0,sizeof(b));
for(int j=i;j<=n;j++){
for(int k=1;k<=m;k++)
b[k]+=a[j][k];
int d=fun(j-i+1);
ans=max(ans,(j-i+1)*d);
}
}
printf("%d\n",ans);
return 0;
}