题目链接:http://www.51nod.com/Challenge/Problem.html#problemId=1157
1157 全是1的最大子矩阵
给出1个M*N的矩阵M1,里面的元素只有0或1,找出M1的一个子矩阵M2,M2中的元素只有1,并且M2的面积是最大的。输出M2的面积。
输入
第1行:2个数m,n中间用空格分隔(2 <= m,n <= 100) 第2 - N + 1行:每行m个数,中间用空格分隔,均为0或1。
输出
输出最大全是1的子矩阵的面积。
输入样例
3 3
1 1 0
1 1 1
0 1 1
输出样例
4
思路:枚举以当前所在位置的高度为真正高度,向左和向右最远能走到哪,存储最大值就行
看代码:
#include<iostream> #include<algorithm> using namespace std; const int maxn=1e2+5; int a[maxn][maxn]; int h[maxn];//存该列往上有多少个1 int l[maxn],r[maxn]; int main() { int N,M; int ans=0; cin>>N>>M; for(int i=1;i<=N;i++) for(int j=1;j<=M;j++) cin>>a[i][j]; for(int i=1;i<=N;i++) { for(int j=1;j<=M;j++) { // cout<<"*"<<endl; if(a[i][j]==1) h[j]++; else h[j]=0; } h[0]=h[M+1]=-1; for(int j=1;j<=M;j++) { // cout<<"**"<<endl; int k=j; while(h[j]<=h[k-1]) k=l[k-1]; l[j]=k; } // cout<<1<<endl; for(int j=M;j>=1;j--) { // cout<<"***"<<endl; int k=j; while(h[j]<=h[k+1]) k=r[k+1]; r[j]=k; } for(int j=1;j<=M;j++) { // cout<<"****"<<endl; int x=h[j]*(r[j]-l[j]+1); ans=max(ans,x); } } cout<<ans<<endl; return 0; }
#include<iostream> #include<algorithm> using namespace std; const int maxn=1e2+5; int a[maxn][maxn]; int h[maxn];//存该列往上有多少个1 int l[maxn],r[maxn]; int main() { int N,M; int ans=0; cin>>N>>M; for(int i=1;i<=N;i++) for(int j=1;j<=M;j++) cin>>a[i][j]; for(int i=1;i<=N;i++) { for(int j=1;j<=M;j++) { // cout<<"*"<<endl; if(a[i][j]==1) h[j]++; else h[j]=0; } h[0]=h[M+1]=-1; for(int j=1;j<=M;j++) { // cout<<"**"<<endl; int k=j; while(h[j]<=h[k-1]) k=l[k-1]; l[j]=k; } // cout<<1<<endl; for(int j=M;j>=1;j--) { // cout<<"***"<<endl; int k=j; while(h[j]<=h[k+1]) k=r[k+1]; r[j]=k; } for(int j=1;j<=M;j++) { // cout<<"****"<<endl; int x=h[j]*(r[j]-l[j]+1); ans=max(ans,x); } } cout<<ans<<endl; return 0; }