City Game UVALive - 3029(悬线法求最大子矩阵)

题意:多组数据(国外题好像都这样),每次n*m矩形,F表示空地,R表示障碍

   求最大子矩阵(悬线法模板)

 

把每个格子向上延伸的空格看做一条悬线

以le[i][j],re[i][j],up[i][j]分别记录该悬线向左,向右的运动极限以及向上的延伸长度

ans=max(ans,(up[i][j]*(re[i][j]-le[i][j]+1)));

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
#define int long long
#define olinr return
#define _ 0
#define love_nmr 0
#define DB double
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-')
            f=-f;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}
inline void put(int x)
{
    if(x<0)
    {
        x=-x;
        putchar('-');
    }
    if(x>9)
        put(x/10);
    putchar(x%10+'0');
}
int n;
int m;
bool mp[1050][1050];
int le[1050][1050];
int re[1050][1050];
int up[1050][1050];
int T;
inline void init()
{
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            char ch=getchar();
            while(!isupper(ch)) ch=getchar();
            if(ch=='F')
                mp[i][j]=true;
            else
                mp[i][j]=false;
        }
}
inline int work()
{
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        int l=0;    //当前障碍的位置
        int r=m+1;
        for(int j=1;j<=m;j++)
        {
            if(!mp[i][j])        //有障碍
            {
                up[i][j]=le[i][j]=0;      
                l=j;       
            }
            else
            {
                up[i][j]=i==1? 1:up[i-1][j]+1;    //更新
                le[i][j]=i==1? l+1:max(le[i-1][j],l+1);
            }
        }
        for(int j=m;j>=1;j--)
        {
            if(!mp[i][j])
            {
                re[i][j]=m+1;
                r=j;
            }
            else
            {
                re[i][j]=i==1? r-1:min(r-1,re[i-1][j]);   //更新re
                ans=max(ans,up[i][j]*(re[i][j]-le[i][j]+1));   //更新答案
            }
        }
    }
    return ans*3;   //要求面积*3
}
signed main()
{
    T=read();
    while(T--)
    {
        n=read();
        m=read();
        init();
        put(work());
        putchar('\n');
    }
    olinr ~~(0^_^0)+love_nmr;
}
/*
2
5 6
RFFFFF
FFFFFF
RRRFFF
FFFFFF
FFFFFF
5 5
RRRRR
RRRRR
RRRRR
RRRRR
RRRRR
*/

 

posted @ 2018-09-05 08:56  olinr  阅读(238)  评论(0编辑  收藏  举报