博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CodeForces 1200D White Lines
阅读量:5312 次
发布时间:2019-06-14

本文共 3567 字,大约阅读时间需要 11 分钟。

  • Time limit

    1500 ms

  • Memory limit

    262144 kB

解题思路

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 l -th column and the last appearance of a black cell is at the r r -th column, we can determine whether it becomes a white line when a certain cell (i,j) (i,j) is clicked in O(1) O(1) , after some preprocessing. It becomes a white line if and only if a cell (i,j) (i,j) is clicked where the row is at [i,i+k1] [i,i+k−1] and jlrj+k1 j≤l≤r≤j+k−1 . We just need to compute l l and r r in advance.

Now let's consider all 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) (1,1) is clicked, by applying the above method to all rows from 1 1 to 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) (1,1) is clicked. From now, we slide the window. Add the k+1 k+1 -st row and remove the 1 1 -st row by applying the same method to them, and we obtain the number of white rows when the cell (2,1) (2,1) is clicked. We can repeat this until we calculate all nk+1 n−k+1 cases for clicking the cells at the 1 1 -st column. Then we repeat the whole process for all nk+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) O(n2)

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

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

感想

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

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

源代码

#include
#include
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;}

转载于:https://www.cnblogs.com/wawcac-blog/p/11355416.html

你可能感兴趣的文章
创新课程管理系统数据库设计心得
查看>>
Hallo wolrd!
查看>>
16下学期进度条2
查看>>
Could not resolve view with name '***' in servlet with name 'dispatcher'
查看>>
Chapter 3 Phenomenon——12
查看>>
和小哥哥一起刷洛谷(1)
查看>>
遇麻烦,Win7+Ubuntu12.10+Archlinux12.10 +grub
查看>>
SqlBulkCopy大批量导入数据
查看>>
pandas 修改指定列中所有内容
查看>>
「 Luogu P2285 」打鼹鼠
查看>>
lua语言入门之Sublime Text设置lua的Build System
查看>>
vue.js基础
查看>>
电脑的自带图标的显示
查看>>
[转载] redis 的两种持久化方式及原理
查看>>
C++ 删除字符串的两种实现方式
查看>>
ORA-01502: 索引'P_ABCD.PK_WEB_BASE'或这类索引的分区处于不可用状态
查看>>
Java抽象类和接口的比较
查看>>
开发进度一
查看>>
MyBaits学习
查看>>
管道,数据共享,进程池
查看>>