暂时的 rk1
看到题目发现很像 棋盘制作 。
稍加变形,
令
l
l
表示不包含 且所在列包含一个
#
#
最长向左延伸多少
令
r
r
表示不包含 且所在列包含一个
#
#
最长向右延伸多少
令
l1
l
1
表示不包含
#
#
且所在列不包含
#
#
最长向左延伸多少
令
r1
r
1
表示不包含
#
#
且所在列不包含
#
#
最长向右延伸多少
令
l2
l
2
表示包含一个
#
#
且所在列不包含
#
#
最长向左延伸多少
令
r2
r
2
表示包含一个
#
#
且所在列不包含
#
#
最长向右延伸多少
然后就可以在每一个位置推出当前位置的最大矩形面积
c++代码如下:
#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i = x ; i <= y; ++ i)
#define repd(i,x,y) for(register int i = x ; i >= y; -- i)
typedef long long ll;
using namespace std;
template<typename T>inline bool chkmin(T&x,T y){ return x > y?x=y,1:0; }
template<typename T>inline bool chkmax(T&x,T y){ return x < y?x=y,1:0; }
template<typename T>inline void read(T&x)
{
char c;int sign = 1;x = 0;
do { c = getchar(); if(c == '-') sign = -1; }while(!isdigit(c));
do { x = x * 10 + c - '0'; c = getchar(); }while(isdigit(c));
x *= sign;
}
const int N = 2018;
int n,m,ans;
int u[N],d[N],l[N],r[N],l1[N],r1[N],l2[N],r2[N];
char s[N];
int main()
{
read(n); read(m);
rep(i,1,m) r[i] = r1[i] = r2[i] = m,l[i] = l1[i] = l2[i] = 1;
rep(k,1,n)
{
scanf("%s",s+1);
int x = 1,y = 1;
rep(i,1,m)
{
chkmax(l[i], x);
if(l1[i] < y) l2[i] = l1[i],l1[i] = y;
else if(l2[i] < y) l2[i] = y;
if(l1[i] < x) l2[i] = l1[i],l1[i] = x;
else if(l2[i] < x) l2[i] = x;
if(s[i] == '#') y = x,x = i + 1;
}
x = m,y = m;
repd(i,m,1)
{
chkmin(r[i],x);
if(r1[i] > y) r2[i] = r1[i],r1[i] = y;
else if(r2[i] > y) r2[i] = y;
if(r1[i] > x) r2[i] = r1[i],r1[i] = x;
else if(r2[i] > x) r2[i] = x;
if(s[i] == '#') y = x,x = i - 1;
}
rep(i,1,m)
if(s[i] == '.'){
++u[i]; ++ d[i];
}else{
d[i] = u[i] + 1; u[i] = 0;
l[i] = l1[i];r[i] = r1[i];
l1[i] = l2[i] = 1;
r1[i] = r2[i] = m;
}
rep(i,1,m)
{
chkmax(ans,(r[i] - l[i] + 1) * d[i]);
chkmax(ans,(r2[i] - l1[i] + 1)*u[i]);
chkmax(ans,(r1[i] - l2[i] + 1)*u[i]);
}
}
cout << ans << endl;
return 0;
}