3726: PA2014Final Wykladzina

这里写图片描述
暂时的 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值