纯 暴 力 很 容 易 想 纯暴力很容易想 纯暴力很容易想
预 处 理 每 行 每 列 最 左 ( 上 ) 的 B 和 最 右 ( 下 ) 的 B 预处理每行每列最左(上)的B和最右(下)的B 预处理每行每列最左(上)的B和最右(下)的B
然 后 O ( n 2 ) 枚 举 每 个 点 作 为 正 方 形 左 上 角 , O ( n ) 判 断 , 显 然 超 时 。 然后O(n^2)枚举每个点作为正方形左上角,O(n)判断,显然超时。 然后O(n2)枚举每个点作为正方形左上角,O(n)判断,显然超时。
考虑如何O(1)判断每个点的贡献
预 处 理 s u m 1 [ i ] [ j ] 表 示 前 i 行 覆 盖 [ j , j + k − 1 ] 列 的 格 子 产 生 的 白 线 预处理sum1[i][j]表示前i行覆盖[j,j+k-1]列的格子产生的白线 预处理sum1[i][j]表示前i行覆盖[j,j+k−1]列的格子产生的白线
预 处 理 s u m 2 [ i ] [ j ] 表 示 前 j 列 覆 盖 [ i , i + k − 1 ] 行 的 格 子 产 生 的 白 线 预处理sum2[i][j]表示前j列覆盖[i,i+k-1]行的格子产生的白线 预处理sum2[i][j]表示前j列覆盖[i,i+k−1]行的格子产生的白线
那 么 以 i , j 为 左 上 角 , 贡 献 就 是 那么以i,j为左上角,贡献就是 那么以i,j为左上角,贡献就是
s u m 1 [ i + k − 1 ] [ j ] − s u m 1 [ i − 1 ] [ j ] + s u m 2 [ j + k − 1 ] [ i ] − s u m 2 [ j − 1 ] [ i ] sum1[i+k-1][j]-sum1[i-1][j]+sum2[j+k-1][i]-sum2[j-1][i] sum1[i+k−1][j]−sum1[i−1][j]+sum2[j+k−1][i]−sum2[j−1][i]
#include <bits/stdc++.h>
using namespace std;
const int maxn=2009;
int r[maxn][maxn],d[maxn][maxn],n,k;
int sum1[maxn][maxn],sum2[maxn][maxn];
char s[maxn][maxn];
int main()
{
cin >> n >> k;
for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
r[i][j]=r[i][j-1]+(s[i][j]=='B');
d[j][i]=d[j][i-1]+(s[i][j]=='B');
}
int tot=0,ans=0;
for(int i=1;i<=n;i++){
if(r[i][n]==0) tot++;
if(d[i][n]==0) tot++;
}
for(int i=1;i<=n;i++)
for(int j=1;j+k-1<=n;j++)
{
//第j到j+k-1个字母被覆盖
sum1[i][j]=sum1[i-1][j]+( r[i][j+k-1]-r[i][j-1]==r[i][n]&&r[i][n]!=0 );
sum2[i][j]=sum2[i-1][j]+( d[i][j+k-1]-d[i][j-1]==d[i][n]&&d[i][n]!=0 );
}
for(int i=1;i<=n-k+1;i++)
for(int j=1;j<=n-k+1;j++)
ans=max(ans, tot+sum1[i+k-1][j]-sum1[i-1][j]+sum2[j+k-1][i]-sum2[j-1][i]);
cout << ans;
}