题意
传送门 NC 14294
题解
考虑动态规划,然后枚举蝴蝶位置。显然,对于剪枝而言,枚举顶点比枚举中心在蝴蝶对角线长度较大时效果更好。
d
[
i
]
[
j
]
,
d
l
[
i
]
[
j
]
,
d
r
[
i
]
[
j
]
d[i][j], dl[i][j], dr[i][j]
d[i][j],dl[i][j],dr[i][j] 分别代表
(
i
,
j
)
(i,j)
(i,j) 向下、左下与右下最大的连续
′
X
′
'X'
′X′ 长度(包括这个点)
d
[
i
]
[
j
]
=
{
d
[
i
+
1
]
[
j
]
+
1
m
a
t
[
i
]
[
j
]
=
′
X
′
0
o
t
h
e
r
w
i
s
e
d[i][j]=\begin{cases} d[i+1][j]+1 & mat[i][j]='X' \\ 0 & otherwise\\ \end{cases}
d[i][j]={d[i+1][j]+10mat[i][j]=′X′otherwise
d
l
[
i
]
[
j
]
=
{
d
[
i
+
1
]
[
j
−
1
]
+
1
m
a
t
[
i
]
[
j
]
=
′
X
′
0
o
t
h
e
r
w
i
s
e
dl[i][j]=\begin{cases} d[i+1][j-1]+1 & mat[i][j]='X' \\ 0 & otherwise\\ \end{cases}
dl[i][j]={d[i+1][j−1]+10mat[i][j]=′X′otherwise
d
r
[
i
]
[
j
]
=
{
d
[
i
+
1
]
[
j
+
1
]
+
1
m
a
t
[
i
]
[
j
]
=
′
X
′
0
o
t
h
e
r
w
i
s
e
dr[i][j]=\begin{cases} d[i+1][j+1]+1 & mat[i][j]='X' \\ 0 & otherwise\\ \end{cases}
dr[i][j]={d[i+1][j+1]+10mat[i][j]=′X′otherwise
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 2005
int n, m, d[maxn][maxn], dl[maxn][maxn], dr[maxn][maxn];
int main()
{
scanf("%d%d", &n, &m);
for (int i = n; i > 0; i--)
{
for (int j = m; j > 0; j--)
{
char c;
scanf(" %c", &c);
if (c == 'X')
{
d[i][j] = d[i + 1][j] + 1;
dl[i][j] = dl[i + 1][j - 1] + 1;
dr[i][j] = dr[i + 1][j + 1] + 1;
}
}
}
int res = 0;
for (int i = 1; i + res <= n; i++)
{
for (int j = 1; j + res <= m; j++)
{
int limit = min(dr[i][j], d[i][j]);
if (!(limit & 1))
--limit;
for (int k = limit; k > res; k -= 2)
{
int j2 = j + k - 1;
if (dl[i][j2] >= k && d[i][j2] >= k)
{
res = k;
break;
}
}
}
}
printf("%d\n", res);
return 0;
}