cf题面

- Time limit

1500 ms

  • Memory limit

    262144 kB

解题思路

官方题解

1200D - White Lines

Let's consider a single row that contains at least one black cell. If the first appearance of a black
cell is at the l"
role="presentation" style="position: relative;">
l

l

-th column and the last appearance of a
black cell is at the r"
role="presentation" style="position: relative;">
r

r

-th column, we can determine whether it
becomes a white line when a certain cell (i,j)"
role="presentation" style="position: relative;">
(i,j)

(
i
,
j
)

is clicked in O(1)"
role="presentation" style="position: relative;">
O(1)

O
(
1
)

, after some preprocessing. It becomes
a white line if and only if a cell (i,j)"
role="presentation" style="position: relative;">
(i,j)

(
i
,
j
)

is clicked where the row is at [i,i+k−1]"
role="presentation" style="position: relative;">
[i,i+k−1]

[
i
,
i
+
k

1
]

and j≤l≤r≤j+k−1"
role="presentation" style="position: relative;">
j≤l≤r≤j+k−1

j

l

r

j
+
k

1

. We just need to
compute l"
role="presentation" style="position: relative;">
l

l

and r"
role="presentation" style="position: relative;">
r

r

in advance.

Now let's consider all n"
role="presentation" style="position: relative;">
n

n

rows (not columns). First, count all
rows that are already white lines before clicking. Then we count the number of white rows when the
cell (1,1)"
role="presentation" style="position: relative;">
(1,1)

(
1
,
1
)

is clicked, by applying the above
method to all rows from 1"
role="presentation" style="position: relative;">
1

1

to k"
role="presentation" style="position: relative;">
k

k

. Ignore the already-white rows that we
counted before. So far we obtained the number of white rows when the cell (1,1)"
role="presentation" style="position: relative;">
(1,1)

(
1
,
1
)

is clicked. From now, we slide the window. Add the k+1"
role="presentation" style="position: relative;">
k+1

k
+
1

-st row and remove the 1"
role="presentation" style="position: relative;">
1

1

-st row by applying the same method to
them, and we obtain the number of white rows when the cell (2,1)"
role="presentation" style="position: relative;">
(2,1)

(
2
,
1
)

is clicked. We can repeat this until
we calculate all n−k+1"
role="presentation" style="position: relative;">
n−k+1

n

k
+
1

cases for clicking the cells at the
1"
role="presentation" style="position: relative;">
1

1

-st column. Then we repeat the whole
process for all n−k+1"
role="presentation" style="position: relative;">
n−k+1

n

k
+
1

columns.

The same process can be done for counting white columns, too. Now we know the number of white rows
and white columns when each cell is clicked, so we can find the maximum value among their sums.

Time complexity: O(n2)"
role="presentation" style="position: relative;">
O(n2)

O
(

n
2

)

可以说是十分暴力了,cf上打的标签有brute force。一个优化就是把橡皮覆盖的区域一格一格地移动,这样就可以\(O(1)\)更新边界了,(突然想到滑动窗口,虽然和这题关系不大)。还有个标签是尺取法,好像也没毛病,滑动区域,更新边界,这确实可以算简化的尺取或者双指针吧……

另外,由于滑动区域的时候,左右滑只能快速更新空白列数,不能快速更新空白行数,上下滑同理,所以行和列分开处理,各自来一遍

感想

本来这题没有必要写博客的,但太兴奋了,真的。写完代码,改好CE以后,样例一遍过,半信半疑交上去,居然就AC了!

回想暑假集训这一个月,蠢得跟啥使得,集训题的做题记录,同样是一片绿,别人的就一个AC时间,我的除了AC时间,下方全都有“-1”“-2”“-3”(失败的提交次数)……每个小错都要浪费我至少两个小时……好几次花半天时间,找到了诸如continue写成return、数组下标或者变量写错之类的错,太憋屈了…………

源代码

#include<cstdio>
#include<algorithm>
int n,k;
const int MAXN=2e3+4;
int u[MAXN],d[MAXN],l[MAXN],r[MAXN]; int ansrow[MAXN][MAXN],anscol[MAXN][MAXN],wrow,wcol; int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
char s[2010];
scanf("%s",s+1);
for(int j=1;j<=n;j++)
{
if(s[j]=='B')
{
r[i]=j;
if(!l[i]) l[i]=j;
d[j]=i;
if(!u[j]) u[j]=i;
}
}
}
for(int i=1;i<=n;i++)
{
if(u[i]==0) wcol++;
if(l[i]==0) wrow++;
}
//先是列
for(int i=1;i+k-1<=n;i++)//对于每一行
{
for(int ii=1;ii<=k;ii++)//统计每行开头区域的答案
if(d[ii]&&d[ii]<=i+k-1&&u[ii]>=i) anscol[i][1]++;
for(int j=2;j+k-1<=n;j++)//将统计区域向右滑动
{
anscol[i][j]=anscol[i][j-1];
if(d[j-1]&&d[j-1]<=i+k-1&&u[j-1]>=i) anscol[i][j]--;
if(d[j+k-1]&&d[j+k-1]<=i+k-1&&u[j+k-1]>=i) anscol[i][j]++;
}
}
//然后行也来一遍
for(int i=1;i+k-1<=n;i++)
{
for(int ii=1;ii<=k;ii++)//统计每列开头区域的答案
if(r[ii]&&r[ii]<=i+k-1&&l[ii]>=i) ansrow[1][i]++;
for(int j=2;j+k-1<=n;j++)//将统计区域向下滑动
{
ansrow[j][i]=ansrow[j-1][i];
if(r[j-1]&&r[j-1]<=i+k-1&&l[j-1]>=i) ansrow[j][i]--;
if(r[j+k-1]&&r[j+k-1]<=i+k-1&&l[j+k-1]>=i) ansrow[j][i]++;
}
}
int ans=-1;
for(int i=1;i+k-1<=n;i++)
{
for(int j=1;j+k-1<=n;j++)
ans=std::max(ans,anscol[i][j]+ansrow[i][j]);
}
printf("%d\n",ans+wcol+wrow);
return 0;
}

CodeForces 1200D White Lines的更多相关文章

  1. White Lines

    D. White Lines 主要思路就是利用差分 对于行:如果在某一个点上,向右下角涂掉 k*k 的矩形能够使得新出现一行 "B" 那么就在这个点上 +1(这里的加 +1 需要利 ...

  2. D. White Lines

    D. White Lines 给定一个$n\times n$的$WB$矩阵,给定一个$k*k$的能把$B$变成$W$的橡皮擦,求橡皮擦作用一次后,全为$W$的行.列总数最大值 前缀和差分 #inclu ...

  3. CF1200D White Lines | 前缀和

    传送门 Examples input 1 4 2 BWWW WBBW WBBW WWWB output 1 4 input 2 3 1 BWB WWB BWB output 2 2 input 3 5 ...

  4. codeforces 872E. Points, Lines and Ready-made Titles

    http://codeforces.com/contest/872/problem/E E. Points, Lines and Ready-made Titles time limit per te ...

  5. Codeforces 870E Points, Lines and Ready-made Titles:并查集【两个属性二选一】

    题目链接:http://codeforces.com/problemset/problem/870/E 题意: 给出平面坐标系上的n个点. 对于每个点,你可以画一条经过这个点的横线或竖线或什么都不画. ...

  6. codeforce D. White Lines

    二维前缀和 给你一个n*n的矩阵,里面有两种字符,‘W’和‘B’,代表black 和white .其实这个矩阵就是一个方形画板,你有一个k*k的橡皮只能用一次,使k*k的矩阵里的B变成W,问完全空白的 ...

  7. Codeforces 870E Points, Lines and Ready-made Titles 计数

    题目链接 题意 给定二维坐标上的\(n\)个点,过每个点可以 画一条水平线 或 画一条竖直线 或 什么都不画,并且若干条重合的直线被看做同一条.问共可能得到多少幅不同的画面? 题解 官方题解 仆の瞎扯 ...

  8. CF1200D 【White Lines】

    退役快一年了之后又打了场紧张刺激的$CF$(斜眼笑) 然后发现$D$题和题解里的大众做法不太一样 (思路清奇) 题意不再赘述,我们可以看到这个题~~好做~~在只有一次擦除机会,尝试以此为突破口解决问题 ...

  9. cf1200 D White Lines(二维差分)

    题目大意 有一个大小为n的矩阵,每个1*1的单位为黑或白,我们可以用一个(只有一个)大小为k*k的白色矩阵覆盖,问:最多的时候有几条白线(横的全为白 或竖的全为白 即为白线). 思路 要想把一条线(以 ...

随机推荐

  1. webdriver中判断元素是否存在的方法

    selenium.webdriver中没有内置的判断元素是否存在的方法,所以定义一个方法,如果找到该元素则返回True,否则返回False: from selenium import webdrive ...

  2. poj3761(反序表)

    题目链接:https://vjudge.net/problem/POJ-3761 题意:给出n和k,求通过k趟冒泡排序得到长为n的有序排列(元素为n个不同的数)的原排列有多少个. 思路: 先给出反序表 ...

  3. 通过U盘或CD/DVD装centos7,出现“dracut-initqueue timeout..."解决办法

    1.在用CD/DVD挂载centos7镜像安装系统时,出现“dracut-initqueue timeout...", :/# cd dev :/# ls 2.这是因为安装程序未能找到安装文 ...

  4. ActiveMQ消息过滤

    前言 ActiveMQ提供了一种机制,使用它,消息服务可根据消息选择器中的标准来执行消息过滤.生产者可在消息中放入应用程序特有的属性,而消费者可使用基于这些属性的选择标准来表明对消息是否感兴趣.这就简 ...

  5. MySQL on duplicate key update 批量插入并更新已存在数据

    业务上经常存在一种现象,需要批量往表中插入多条数据,但在执行过程中,很可能因为唯一键冲突,而导致批量插入失败.因此需要事先判断哪些数据是重复的,哪些是新增的.比较常用的处理方法就是找出已存在的数据,并 ...

  6. MySQL水平分表

    业务表增长速度较快,单表数据较大,对表的读写有影响. 思路:化整为零,把单表拆解为多表,按指定的算法规则选择表. 好处:能大幅降低单表的数据,读写更快,同时分散了表数据, SQL语句也分散到不同的表中 ...

  7. TS学习

    随着vue3.0的即将到来,是时候学习一下TS了 简介:TypeScript是一种由微软开发的自由和开源的编程语言.它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类 ...

  8. 错误 “SCRIPT7002: XMLHttpRequest: 网络错误 0x2ef3, ie浏览器兼容问题

    参考:https://www.telerik.com/blogs/help!-running-fiddler-fixes-my-app- https://www.cnblogs.com/OpenCod ...

  9. Vue.nextTick 的原理和用途

    转载自https://segmentfault.com/a/1190000012861862 概览 官方文档说明: 用法: 在下次 DOM 更新循环结束之后执行延迟回调.在修改数据之后立即使用这个方法 ...

  10. ShareSdk等等(三方登录与支付冲突问题)

    1.必须实现前两个方法,第三个方法照成支付回调有问题. //必须实现的方法 - (BOOL)application:(UIApplication *)application handleOpenURL ...