最大纯矩阵
2
做法:设 \(l_{i,j}\) 表示 \(i,j\) 一直往左走直到走不通的 \(F\) 的纵坐标, \(r_{i,j}\) 表示 \(i,j\) 一直往右走直到走不通的 \(F\) 的纵坐标, \(h_{i,j}\) 表示 \(i,j\) 一直向上走直
大小到走不通的距在1
\(l ~,~ r ~,~h\) 都很好求。
然后我们怎么算呢?对于一个点 \(i,j\) ,我们要算的是以第 \(i\) 行为底,底边包含 \(i,j\),高为 \(h_{i,j}\) 的最大矩形。实际情况中,也许会出现“凸”字形的情况,这时位于“凸”的肚子上的点,它们要算的矩形的 \(l\) 和 \(r\) 并不是它自己的 \(l\) 和 \(r\) ,所以要从它上面的点更新 \(l\) 和 \(r\) 。这样做是没问题的,因为一列中下面的点肯定要考虑所有上面点的限制,而且我们从上往下遍历, \(l\) 和 \(r\) 被更改了肯定对正确性是没有影响的。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 5;
bool mp[N][N];
int l[N][N], r[N][N], h[N][N];
int n, m;
int res;
char v;
inline int read()
{
int x = 0;
while(!isdigit(v)) v = getchar();
while(isdigit(v)) x = (x << 1) + (x << 3) + v - 48, v = getchar();
return x;
}
int main()
{
n = read(); m = read();
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
{
while((v ^ 'R') && (v ^ 'F')) v = getchar();
mp[i][j] = (v ^ 'R') ? true : false;
v = getchar();
}
for(int i = 1 ; i <= n; ++i)
for(int j = 1; j <= m; ++j)
if(mp[i][j])
{
if(mp[i][j - 1])
l[i][j] = l[i][j - 1];
else
l[i][j] = j;
}
for(int i = 1; i <= n; ++i)
for(int j = m; j; --j)
if(mp[i][j])
{
if(mp[i][j + 1])
r[i][j] = r[i][j + 1];
else r[i][j] = j;
}
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
if(mp[i][j])
{
h[i][j] = h[i - 1][j] + 1;
if(mp[i - 1][j])
{
l[i][j] = max(l[i][j], l[i - 1][j]);
r[i][j] = min(r[i][j], r[i - 1][j]); //此处更新l,r
}
res = max(res, (r[i][j] - l[i][j] + 1) * h[i][j]);
}
cout << 3 * res;
return 0;
}

浙公网安备 33010602011771号