极大全1矩阵
悬线法:悬线的定义,就是一条竖线,这条竖线要满足上端点在整个矩形上边界或者是一个障碍点。然后以这条悬线进行左右移动,直到移至障碍点或者是矩阵边界,进而确定这条悬线所在的极大矩阵。
一些定义:
up[i][j]为矩阵上的点(i,j)向上的悬线长度
lft[i][j]为矩阵上的点(i,j)向左扩展而不会碰到障碍点的长度
rgt[i][j]为矩阵上的点(i,j)向右扩展而不会碰到障碍点的长度
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<stack> #include<cstdlib> #include<queue> #include<set> #include<string.h> #include<vector> #include<deque> #include<map> using namespace std; #define INF 0x3f3f3f3f3f3f3f3f #define inf 0x3f3f3f3f #define eps 1e-4 #define bug printf("********* ") #define debug(x) cout<<#x"=["<<x<<"]" <<endl typedef long long LL; typedef long long ll; const int maxn = 2e3 + 5; const int mod = 998244853; char s[maxn][maxn]; int up[maxn][maxn],lft[maxn][maxn],rgt[maxn][maxn]; int main() { int n, m; scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { scanf(" %c", s[i] + j); lft[i][j] = rgt[i][j] = j; up[i][j] = 1; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) if (s[i][j] == '1' && s[i][j - 1] == '1') lft[i][j] = lft[i][j - 1]; for (int j = m; j >= 1; j--) if (s[i][j] == '1' && s[i][j + 1] == '1') rgt[i][j] = rgt[i][j + 1]; } int ans = 0; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (i > 1 && s[i][j] == '1' && s[i - 1][j] == '1') { lft[i][j] = max(lft[i][j], lft[i - 1][j]); rgt[i][j] = min(rgt[i][j], rgt[i - 1][j]); up[i][j] = up[i - 1][j] + 1; } ans = max(ans, (rgt[i][j] - lft[i][j] + 1) * up[i][j]); } } printf("%d ",ans); }