Butterfly

Butterfly
时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld

题目描述

给定一个n*m的矩阵,矩阵元素由X和O构成,请求出其中最大的由X构成的蝴蝶形状。
由X构成的蝴蝶形状的定义如下:
存在一个中心点,并且其往左上、左下、右上、右下四个方向扩展相同的长度(扩展的长度上都是X),且左上顶点与左下顶点、右上顶点与右下顶点之间的格子全由X填充。我们不在意在蝴蝶形状内部是X还是O。
例如:
    XOOOX
    XXOXX
    XOXOX
    XXOXX
    XOOOX
是一个X构成的蝴蝶形状。
    X
也是。

    XOOX
    OXXO
    OXXO
    XOXX
不是(不存在中心点)。
 

输入描述:

第一行两个整数n, m表示矩阵的大小(1 <= n, m <= 2000);
接下来n行,每行一个长度为m的字符串表示矩阵,矩阵元素保证由X和O构成。

输出描述:

一行一个整数表示最大的由X构成的蝴蝶形状的对角线的长度。
示例1

输入

5 5
XOOOX
XXOXX
XOXOX
XXOXX
XOOOX

输出

5
分析:蝴蝶形状可以分成两部分,|\和/|,预处理每个点这两种情况的最长长度;
   最后枚举答案,bitset快速查询点对即可;
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <bitset>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <cassert>
#include <ctime>
#define rep(i,m,n) for(i=m;i<=(int)n;i++)
#define inf 0x3f3f3f3f
#define mod 998244353
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define sys system("pause")
#define ls (rt<<1)
#define rs (rt<<1|1)
#define all(x) x.begin(),x.end()
const int maxn=2e3+10;
const int N=4e5+10;
using namespace std;
ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qmul(ll p,ll q,ll mo){ll f=0;while(q){if(q&1)f=(f+p)%mo;p=(p+p)%mo;q>>=1;}return f;}
ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p%mod;p=p*p%mod;q>>=1;}return f;}
int n,m,k,t;
short ld[maxn][maxn],rd[maxn][maxn],dd[maxn][maxn];
vector<pair<short,short>>pl[maxn],pr[maxn];
bitset<maxn>bl[maxn],br[maxn];
char a[maxn][maxn];
int main(){
    int i,j;
    scanf("%d%d",&n,&m);
    rep(i,1,n)scanf("%s",a[i]+1);
    for(i=n;i>=1;i--)
    {
        for(j=m;j>=1;j--)
        {
            if(a[i][j]=='X')
            {
                ld[i][j]=ld[i+1][j-1]+1;
                dd[i][j]=dd[i+1][j]+1;
                rd[i][j]=rd[i+1][j+1]+1;
            }
            pl[min(dd[i][j],rd[i][j])].pb(mp(i,j));
            pr[min(dd[i][j],ld[i][j])].pb(mp(i,j));
        }
    }
    rep(i,1,m)rep(j,1,n)bl[i][j]=br[i][j]=1;
    int ret=0;
    for(i=1,j=0;i<=m;i+=2)
    {
        while(j<i)
        {
            for(auto &p:pl[j])bl[p.se][p.fi]=0;
            for(auto &p:pr[j])br[p.se][p.fi]=0;
            j++;
        }
        rep(k,1,m-i+1)if((bl[k]&br[k+i-1]).any())
        {
            ret=i;
            break;
        }
    }
    printf("%d\n",ret);
    return 0;
}
posted @ 2017-10-30 23:07  mxzf0213  阅读(600)  评论(0编辑  收藏  举报