给定一个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
#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize(2)
#define ll long long
char s[2005][2005];
int lup[2005][2005],rup[2005][2005],up[2005][2005],mp[2005][2005],vis[2005][2005],n,m,ans=0;
int main()
{
std::ios_base::sync_with_stdio(false),cin.tie(),cout.tie();
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>s[i][j];
if(s[i][j]=='X')
{
ans=1;
mp[i][j]=0;
lup[i][j]=lup[i-1][j-1]+1;
rup[i][j]=rup[i-1][j+1]+1;
up[i][j]=up[i-1][j]+1;
}
else mp[i][j]=1;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int k=min(rup[i][j],up[i][j]);k>ans;k--)
if(up[i][j+k-1]>=k&&lup[i][j+k-1]>=k&&up[i][j+k-1]>=k&&k%2==1)
ans=max(ans,k);
cout<<ans;
return 0;
}