3 4 1011 1001 0001 3 4 1010 1001 0001
4 2 Note: Huge Input, scanf() is recommended.
最大完全子矩阵,以第i行为底,可以构成的最大矩阵,因为该题可以任意移动列,所以只要大于等于height[i]的都可以移动到一起,求出 height>=height[i]的个数即可
,这里用hash+滚动,先求出height[i]出现的次数,然后逆序扫一遍 hash[i]+=hash[i+1];
#include<bits/stdc++.h> using namespace std; int H[1010][1010]; int T[1010]; char s[1010][1010]; int main() { int n,m; while(~scanf("%d%d",&n,&m)) { for(int i=1;i<=n;i++) scanf("%s",s[i]); memset(H,0,sizeof(H)); for(int i=n;i>=1;i--) { for(int j=1;j<=m;j++) { if(s[i][j-1]=='1') H[i][j]=H[i+1][j]+1; } } int Max=-1; memset(T,0,sizeof(T)); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(H[i][j]!=0) T[H[i][j]]++; //hash统计对应各个高的底 } for(int j=n;j>=1;j--) //hash统计对应出现的各个高,逆推得到底的大小(高大于等于该点的边的数目) T[j]+=T[j+1]; for(int j=1;j<=m;j++) Max=max(Max,H[i][j]*T[H[i][j]]); //求最大的面积 for(int j=1;j<=n;j++) //大小为n T[j]=0; //清空防止累积到下一行 } printf("%d\n",Max); } return 0; }
方法二:
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; bool cmp(int a,int b) { return a > b; } int main() { int R,C,num[1005],a[1005]; while(~scanf("%d%d",&R,&C)) { getchar(); int ans = 0; memset(num,0,sizeof(num)); for(int i=1;i<=R;i++) { for(int j=1;j<=C;j++) { char c = getchar(); if(c == '1') ++num[j]; else num[j] = 0; a[j] = num[j]; } sort(a+1,a+1+C,cmp); //排序 for(int j=1;j<=C && a[j];j++) if(a[j]*j > ans) ans = a[j]*j; getchar(); } printf("%d\n",ans); } return 0; }