Codeforces 679C Bear and Square Grid
枚举k * k 的位置, 然后接上它周围白色连通块的数量, 再统计完全在k * k范围里的连通块, 这个只要某个连通块全部的方格
在k * k里面就好, 并且k * k是一行一行移的, 所以可以优化到n ^ 3。
#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long using namespace std; const int N = + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + ;
const double eps = 1e-;
const double PI = acos(-); int n, k, idx, now, id[N][N], sum[N][N];
bool vis[N * N];
char Map[N][N]; int fa[N * N], cnt[N * N], num[N * N]; int getRoot(int x) {
return fa[x] == x ? x : fa[x] = getRoot(fa[x]);
} void change(int x, int op) {
x = getRoot(x);
if(op == ) {
num[x]--;
if(!num[x]) now += cnt[x];
} else {
if(!num[x]) now -= cnt[x];
num[x]++;
}
}
int main() {
scanf("%d%d", &n, &k);
for(int i = ; i <= n * n; i++) fa[i] = i;
for(int i = ; i <= n; i++)
scanf("%s", Map[i] + );
for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++)
if(Map[i][j] == '.') id[i][j] = ++idx, cnt[idx] = ;
for(int i = ; i <= n; i++) {
for(int j = ; j <= n; j++) {
if(Map[i][j] != '.') continue;
if(Map[i - ][j] == '.') {
int x = getRoot(id[i][j]);
int y = getRoot(id[i - ][j]);
if(x != y) fa[y] = x, cnt[x] += cnt[y];
}
if(Map[i][j - ] == '.') {
int x = getRoot(id[i][j]);
int y = getRoot(id[i][j - ]);
if(x != y) fa[y] = x, cnt[x] += cnt[y];
}
}
}
for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++)
sum[i][j] = sum[i - ][j] + sum[i][j - ] - sum[i - ][j - ] + (Map[i][j] == 'X');
for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++)
if(Map[i][j] == '.') num[getRoot(id[i][j])]++; int ans = ;
queue<int> que; for(int i = ; i + k - <= n; i++) {
for(int j = ; j + k - <= n; j++) {
if(j == ) {
for(int u = i; u < i + k; u++)
for(int v = j; v < j + k; v++)
change(id[u][v], );
}
int ret = ;
if(i - > ) {
for(int z = j; z <= j + k - ; z++) {
if(Map[i - ][z] != '.') continue;
int x = getRoot(id[i - ][z]);
if(!vis[x]) {
vis[x] = true;
que.push(x);
ret += cnt[x];
}
}
}
if(i + k <= n) {
for(int z = j; z <= j + k - ; z++) {
if(Map[i + k][z] != '.') continue;
int x = getRoot(id[i + k][z]);
if(!vis[x]) {
vis[x] = true;
que.push(x);
ret += cnt[x];
}
}
} if(j - > ) {
for(int z = i; z <= i + k - ; z++) {
if(Map[z][j - ] != '.') continue;
int x = getRoot(id[z][j - ]);
if(!vis[x]) {
vis[x] = true;
que.push(x);
ret += cnt[x];
}
}
}
if(j + k <= n) {
for(int z = i; z <= i + k - ; z++) {
if(Map[z][j + k] != '.') continue;
int x = getRoot(id[z][j + k]);
if(!vis[x]) {
vis[x] = true;
que.push(x);
ret += cnt[x];
}
}
}
while(!que.empty()) {
vis[que.front()] = false;
que.pop();
}
ans = max(ans, now + ret + sum[i + k - ][j + k - ] - sum[i - ][j + k - ] - sum[i + k - ][j - ] + sum[i - ][j - ]);
if(j + k <= n) {
for(int z = i; z < i + k; z++) change(id[z][j], -);
for(int z = i; z < i + k; z++) change(id[z][j + k], );
} else {
for(int u = i; u < i + k; u++)
for(int v = j; v < j + k; v++)
change(id[u][v], -);
}
}
}
printf("%d\n", ans);
return ;
} /*
*/
Codeforces 679C Bear and Square Grid的更多相关文章
- codeforces 680E Bear and Square Grid 巧妙暴力
这个题是个想法题 先预处理连通块,然后需要用到一种巧妙暴力,即0变1,1变0,一列列添加删除 复杂度O(n^3) #include <cstdio> #include <iostre ...
- Codeforces Round #356 (Div. 2) E. Bear and Square Grid 滑块
E. Bear and Square Grid 题目连接: http://www.codeforces.com/contest/680/problem/E Description You have a ...
- Codeforces Round #356 (Div. 1) C. Bear and Square Grid
C. Bear and Square Grid time limit per test 3 seconds memory limit per test 256 megabytes input stan ...
- CF679C(Bear and Square Grid) 经典好题
题目链接:传送门 题目大意:给你一个n*n包含".","X"的图,你有一次机会选择一个k*k的子矩阵,将子矩阵全部变为".",问当操作过后, ...
- Codeforces679C. Bear and Square Grid
n<=500,n*n的01矩阵,可以选择一个k*k的矩阵全变1,求最大1联通区域. 敢敢n^3..模拟k*k的矩阵的位置,从左到右扫的时候,每变一个位置只会引起边界的信息变化,就记含边界的k*k ...
- Codeforces 385C Bear and Prime Numbers
题目链接:Codeforces 385C Bear and Prime Numbers 这题告诉我仅仅有询问没有更新通常是不用线段树的.或者说还有比线段树更简单的方法. 用一个sum数组记录前n项和, ...
- Codeforces 385B Bear and Strings
题目链接:Codeforces 385B Bear and Strings 记录下每一个bear的起始位置和终止位置,然后扫一遍记录下来的结构体数组,过程中用一个变量记录上一个扫过的位置,用来去重. ...
- Codeforces Round #448 C. Square Subsets
题目链接 Codeforces Round #448 C. Square Subsets 题解 质因数 *质因数 = 平方数,问题转化成求异或方程组解的个数 求出答案就是\(2^{自由元-1}\) , ...
- Codeforces 680D Bear and Tower of Cubes 贪心 DFS
链接 Codeforces 680D Bear and Tower of Cubes 题意 求一个不超过 \(m\) 的最大体积 \(X\), 每次选一个最大的 \(x\) 使得 \(x^3\) 不超 ...
随机推荐
- log4j入门
日志是应用软件中不可缺少的部分,Apache的开源项目log4j是一个功能强大的日志组件,提供方便的日志记录.在apache网站:jakarta.apache.org/log4j 可以免费下载到Log ...
- dijkstra补充
dijkstra主要写法: priority_queue<pair<int,int> >q; //大根堆 //dis第一维为dis的相反数 void dijkstra(){ m ...
- new和delete
和 sizeof 类似,sizeof不是函数,它是一个操作符,它在编译期就完成了计算,在函数运行期间它已经是一个常数值了. int a; sizeof(int) = 4; sizeof(a) = 4; ...
- cetus系列~ 继续分析
一 简介:我们来继续探讨cetus的细节问题 二 命令 1 select help 查看帮助 2 select * from backends 查看后端列表 3 select conn_detai ...
- 用accessKey设置快捷键
<!DOCTYPE html> <html> <body> <a href="http://www.w3school.com.cn/html/&qu ...
- 批量下载Coursera及其他场景上的文件
以下方法同样适用于其他场景的批量下载. 最近在学习Coursera退出的深度学习课程,我希望把课程提供的作业下载下来以备以后复习,但是课程有很多文件,比如说脸部识别一课中的参数就多达226个csv文件 ...
- ActiveMQ集群
1.ActiveMQ集群介绍 1.为什么要集群? 实现高可用,以排除单点故障引起的服务中断 实现负载均衡,以提升效率为更多客户提供服务 2.集群方式 客户端集群:让多个消费者消费同一个队列 Broke ...
- kali linux 下搭建git服务器
参考:http://www.cnblogs.com/dee0912/p/5815267.html https://www.liaoxuefeng.com/wiki/001373951630592960 ...
- kdevelop 添加对 C++11的支持
工程--打开配置--显示高级--显示高级变量(打钩) CMAKE_CXX_FLAGS 项添加 -std=c++0x
- python之random模块分析(一)
random是python产生伪随机数的模块,随机种子默认为系统时钟.下面分析模块中的方法: 1.random.randint(start,stop): 这是一个产生整数随机数的函数,参数start代 ...