Codeforces Round #578 (Div. 2) D. White Lines(二维差分+前缀和)

题目链接
在这里插入图片描述
在这里插入图片描述
思路:我们分析一下每行和每列(行和列道理其实一样),先来看行,对于i行,如果该行的第一个B的位置l,最后一个B的位置r,r-l+1>=k的时候我们是能用橡皮把这行变全白的,那么它对对哪些为左上角的起点产生贡献呢?这里涉及一点空间想象能力,可以自己图画一下,只要左上角是位于(x1,y1)-(i,l)的矩形区域内都能产生贡献,其中x1=max(0,i-k+1),y1=(0,j-k+1)。贡献的话用二维差分维护一下,计算最大的前缀和就可以了。`

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e3+1;
int n,k,sum[maxn][maxn],cnt[maxn][maxn],ans=0;
char s[maxn][maxn];
int main()
{
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;++i)
	scanf("%s",s[i]+1);
	for(int i=1;i<=n;++i)
	{
		int l=0,r=0;
		for(int j=1;j<=n;++j)
		if(s[i][j]=='B'&&l==0) l=j,r=j;
		else if(s[i][j]=='B') r=j;
		if(l==0) {cnt[1][1]++;continue;}
		if(r-l+1>k) continue;
		int x1=max(1,i-k+1),y1=max(1,r-k+1),x2=i,y2=l;
		cnt[x1][y1]++,cnt[x2+1][y1]--,cnt[x1][y2+1]--,cnt[x2+1][y2+1]++;
	}
	for(int j=1;j<=n;++j)
	{
		int u=0,d=0;
		for(int i=1;i<=n;++i)
		if(s[i][j]=='B'&&u==0) u=i,d=i;
		else if(s[i][j]=='B') d=i;
		if(u==0) {cnt[1][1]++;continue;}
		if(d-u+1>k) continue;
		int x1=max(1,d-k+1),y1=max(1,j-k+1),x2=u,y2=j;
		cnt[x1][y1]++,cnt[x2+1][y1]--,cnt[x1][y2+1]--,cnt[x2+1][y2+1]++;
	}
	for(int i=1;i<=n;++i)
	for(int j=1;j<=n;++j)
	{
	sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+cnt[i][j];
	ans=max(ans,sum[i][j]);
	}
	printf("%d\n",ans);
}
发布了144 篇原创文章 · 获赞 0 · 访问量 4925

猜你喜欢

转载自blog.csdn.net/qq_42479630/article/details/104564898