Butterfly
Posted mxzf0213
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Butterfly相关的知识,希望对你有一定的参考价值。
Butterfly
时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
空间限制: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
不是(不存在中心点)。
由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; }
以上是关于Butterfly的主要内容,如果未能解决你的问题,请参考以下文章