CF1200D White Lines 题解
题目意思
Sol
- 前置知识:二维差分
- 我们首先考虑哪个点为选择正方形的左上角会对改行产生贡献
- 我们对于一行进行考虑,设最左黑格位置为
l,最右黑格为
r,那么如果
r−l+1>m显然无法做出贡献。当我们把一个以
(r−m+1,i−m+1)为左上角,
(i,l)为右下角的矩形才会有贡献(我这个考虑了很久,还是
tcl)。
- 列与行计算贡献方法同理,然后二维前缀和统计最大贡献的位置(选择矩阵左上角)
- 最后我们只要把原本就完整(全部都是白的)计入答案就好了
- 代码会做出清晰的解释
Code
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
inline int read()
{
int sum=0,ff=1; char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-1;
ch=getchar();
}
while(isdigit(ch))
sum=sum*10+(ch^48),ch=getchar();
return sum*ff;
}
const int N=2e3+5;
int n,m,a[N][N],c[N][N],ans;
char ch[N][N];
int main()
{
n=read();
m=read();
for ( int i=1;i<=n;i++ )
scanf("%s",ch[i]+1);
for ( int i=1;i<=n;i++ )
{
int l=n+1,r=0;
for ( int j=1;j<=n;j++ )
if(ch[i][j]=='B')
{
l=min(l,j);
r=max(r,j);
}
if(l==n+1&&!r) ans++;
else
{
if(r-l+1>m) continue;
int sx=max(1,i-m+1),sy=max(1,r-m+1);
int ex=i,ey=l;
a[sx][sy]++;
a[ex+1][ey+1]++;
a[sx][ey+1]--;
a[ex+1][sy]--;
}
}
for ( int i=1;i<=n;i++ )
{
int l=n+1,r=0;
for ( int j=1;j<=n;j++ )
if(ch[j][i]=='B')
{
l=min(l,j);
r=max(r,j);
}
if(l==n+1&&!r) ans++;
else
{
if(r-l+1>m) continue;
int sy=max(1,i-m+1),sx=max(1,r-m+1);
int ey=i,ex=l;
a[sx][sy]++;
a[ex+1][ey+1]++;
a[sx][ey+1]--;
a[ex+1][sy]--;
}
}
for ( int i=1;i<=n;i++ )
for ( int j=1;j<=n;j++ )
c[i][j]+=c[i-1][j]+c[i][j-1]-c[i-1][j-1]+a[i][j];
int cwy=0;
for ( int i=1;i+m-1<=n;i++ )
for ( int j=1;j+m-1<=n;j++ )
cwy=max(cwy,c[i][j]);
ans+=cwy;
printf("%d\n",ans);
return 0;
}