【CF1200D】White Lines【前缀和】

题目大意:

题目链接:https://codeforces.com/problemset/problem/1200/D
给出一个 n × n n\times n n×n的黑白网格图,问用一个 m × m m\times m m×m的白色网格覆盖原图的一部分后最多有多少行列全部为白色。


思路:

考虑对于每一条边,如果我们要把它染成白色,那么对应白色矩形的左上角坐标的区间范围是多少。
假设这条边的最左端黑色位置的下标为 l l l,最右端下标为 r r r,那么这个矩形右边界一定要 ≥ r \geq r r,左边界一定要 ≤ l \leq l l。所以我们算出这个矩形左上角横坐标的区间,用前缀和搞一下即可。
同理,对于纵向的边我们也可以求出横向的区间范围。这样一共有 2 n 2n 2n条边,每条边的最大范围为 m m m,时间复杂度 O ( n m ) O(nm) O(nm)
然后跑一下前缀和就好了。注意答案要加上一开始就全部为白色的数量。


代码:

#include <cstdio>
#include <algorithm>
using namespace std;

const int N=2010;
int n,m,s1[N][N],s2[N][N],ans,cnt;
char ch[N][N];

struct node
{
	int l,r;
}a[N],b[N];

int main()
{
	scanf("%d%d",&n,&m);
	if (m>=n)
	{
		printf("%d",n*2);
		return 0;
	}
	for (int i=1;i<=n;i++)
		for (int j=1;j<=n;j++)
		{
			while (ch[i][j]=getchar()) if (ch[i][j]=='W'||ch[i][j]=='B') break;
			if (ch[i][j]=='B')
			{
				if (!a[i].l) a[i].l=j;
				a[i].r=j;
				if (!b[j].l) b[j].l=i;
				b[j].r=i;
			} 
		}
	for (int i=1;i<=n;i++)
	{
		bool flag=1;
		for (int j=1;j<=n;j++)
			if (ch[i][j]=='B')
			{
				flag=0;
				break;
			}
		if (flag) cnt++;
	}
	for (int i=1;i<=n;i++)
	{
		bool flag=1;
		for (int j=1;j<=n;j++)
			if (ch[j][i]=='B')
			{
				flag=0;
				break;
			}
		if (flag) cnt++;
	}
	for (int i=1;i<=n;i++)
		if (a[i].r-a[i].l+1<=m)
		{
			int l=a[i].l,r=a[i].r;
			for (int j=max(1,i-m+1);j<=i;j++)
				s1[j][max(r-m+1,1)]++,s1[j][l+1]--;
		}
	for (int i=1;i<=n;i++)
		if (b[i].r-b[i].l+1<=m)
		{
			int l=b[i].l,r=b[i].r;
			for (int j=max(1,i-m+1);j<=i;j++)
				s2[max(r-m+1,1)][j]++,s2[l+1][j]--;
		}
	for (int i=1;i<=n;i++)
		for (int j=1;j<=n;j++)
		{
			s1[i][j]+=s1[i][j-1];
			s2[i][j]+=s2[i-1][j];
			if (s1[i][j]+s2[i][j]>ans)
				ans=s1[i][j]+s2[i][j];
		}
	printf("%d",ans+cnt);
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值