题目链接:传送门

题目大意:给你一个n*n包含".","X"的图,你有一次机会选择一个k*k的子矩阵,将子矩阵全部变为".",问当操作过后,得到的最大联通子块包含的"."的数目是多少。

题目思路:其实这个题自己只想到了一个暴力的思路,当然TLE没商量,但实际上正确的想法就是先dfs预处理所有"."的联通块,之后的想法技巧性太强了,

         操作是模拟将子矩阵右移,直接暴力会TLE,而我们可以想到实际上移动的时候我们只需要删掉最左边的一列,加上最右边的一列就达到了移动的子矩阵的目的。

         当然这个题既考验想法又考验码力,但是自己太弱,参考了很多别人的代码。。。努力!

 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cctype>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <climits>
#define lson root<<1,l,mid
#define rson root<<1|1,mid+1,r
#define fi first
#define se second
#define ping(x,y) ((x-y)*(x-y))
#define mst(x,y) memset(x,y,sizeof(x))
#define mcp(x,y) memcpy(x,y,sizeof(y))
using namespace std;
#define gamma 0.5772156649015328606065120
#define MOD 1000000007
#define inf 0x3f3f3f3f
#define N 100005
#define maxn 20005
typedef pair<int,int> PII; int n,k,ans,all,cnt,temp;
char pic[][];
int vis[][];
int color[]; ///子块所含 "." 的数目
int sum[][]; ///二维前缀和,避免一个点重复计数
int vi[]; ///标记数组,记录联通块是否计数过 void dfs(int x,int y){
++temp;
vis[x][y]=cnt;
if(pic[x-][y]=='.'&&!vis[x-][y])dfs(x-,y);
if(pic[x+][y]=='.'&&!vis[x+][y])dfs(x+,y);
if(pic[x][y-]=='.'&&!vis[x][y-])dfs(x,y-);
if(pic[x][y+]=='.'&&!vis[x][y+])dfs(x,y+);
}
inline void del(int x,int y){ ///删点
if(!vis[x][y])return;
int t=vis[x][y];
--vi[t];
if(!vi[t])all-=color[t];
}
inline void ins(int x,int y){ ///加点
if(!vis[x][y])return;
int t=vis[x][y];
if(!vi[t])all+=color[t];
++vi[t];
}
inline int clac(int x,int y){
return sum[x+k-][y+k-]-sum[x+k-][y-]-sum[x-][y+k-]+sum[x-][y-];
}
int main(){
int i,j,group;
scanf("%d%d",&n,&k);
for(i=;i<=n;++i){
scanf("%s",pic[i]+);
for(j=;j<=n;++j){
sum[i][j]=sum[i-][j]+sum[i][j-]-sum[i-][j-];
if(pic[i][j]=='.')++sum[i][j];
} ///二维前缀和,新技能get
}
for(i=;i<=n;++i)for(j=;j<=n;++j)
if(pic[i][j]=='.'&&!vis[i][j]){
++cnt;
temp=;
dfs(i,j);
color[cnt]=temp;
}
for(i=;i<=n-k+;++i){
all=;mst(vi,);
for(j=i-;j<=k+i;++j){
for(int l=;l<=k;++l)
ins(j,l);
}
for(j=i;j<i+k;++j)ins(j,k+);
ans=max(ans,all+k*k-clac(i,));
for(j=;j<=n-k+;++j){
for(int l=i;l<i+k;++l){
del(l,j-);
ins(l,j+k);
}
del(i-,j-);del(i+k,j-);
ins(i-,j+k-);ins(i+k,j+k-);
ans=max(ans,all+k*k-clac(i,j));
}
}
printf("%d\n",ans);
return ;
}

CF679C(Bear and Square Grid) 经典好题的更多相关文章

  1. 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 ...

  2. Codeforces 679C Bear and Square Grid

    Bear and Square Grid 枚举k * k 的位置, 然后接上它周围白色连通块的数量, 再统计完全在k * k范围里的连通块, 这个只要某个连通块全部的方格 在k * k里面就好, 并且 ...

  3. 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 ...

  4. codeforces 680E Bear and Square Grid 巧妙暴力

    这个题是个想法题 先预处理连通块,然后需要用到一种巧妙暴力,即0变1,1变0,一列列添加删除 复杂度O(n^3) #include <cstdio> #include <iostre ...

  5. Codeforces679C. Bear and Square Grid

    n<=500,n*n的01矩阵,可以选择一个k*k的矩阵全变1,求最大1联通区域. 敢敢n^3..模拟k*k的矩阵的位置,从左到右扫的时候,每变一个位置只会引起边界的信息变化,就记含边界的k*k ...

  6. 经典算法题每日演练——第十七题 Dijkstra算法

    原文:经典算法题每日演练--第十七题 Dijkstra算法 或许在生活中,经常会碰到针对某一个问题,在众多的限制条件下,如何去寻找一个最优解?可能大家想到了很多诸如“线性规划”,“动态规划” 这些经典 ...

  7. 经典算法题每日演练——第十六题 Kruskal算法

    原文:经典算法题每日演练--第十六题 Kruskal算法 这篇我们看看第二种生成树的Kruskal算法,这个算法的魅力在于我们可以打一下算法和数据结构的组合拳,很有意思的. 一:思想 若存在M={0, ...

  8. 经典算法题每日演练——第十四题 Prim算法

    原文:经典算法题每日演练--第十四题 Prim算法 图论在数据结构中是非常有趣而复杂的,作为web码农的我,在实际开发中一直没有找到它的使用场景,不像树那样的频繁使用,不过还是准备 仔细的把图论全部过 ...

  9. 经典算法题每日演练——第十一题 Bitmap算法

    原文:经典算法题每日演练--第十一题 Bitmap算法 在所有具有性能优化的数据结构中,我想大家使用最多的就是hash表,是的,在具有定位查找上具有O(1)的常量时间,多么的简洁优美, 但是在特定的场 ...

随机推荐

  1. 通过SectionIndexer实现微信通讯录

    这里主要参考了使用SectionIndexer实现微信通讯录的效果 在这里做个记录 效果图 页面使用RelativeLayout,主要分为三个部分,match_parent的主listView,右边字 ...

  2. Hibernate JPA实体继承的映射(二) @MappedSuperclass

    基于代码复用和模型分离的思想,在项目开发中使用JPA的@MappedSuperclass注解将实体类的多个属性分别封装到不同的非实体类中. 1.@MappedSuperclass注解只能标准在类上:@ ...

  3. 点滴积累【JS】---JQuery实现条形统计图,适用于选择题等统计

    效果: 思路:前台JS实现动态数据效果,后台可以拼接字符串或者用JSON加载数据 代码: <%@ Page Language="C#" AutoEventWireup=&qu ...

  4. 点滴积累【C#】---C#实现上传照片到物理路径,并且将地址保存到数据库,

    效果: 思路: 首先,获取图片物理地址,然后进行判断将图片保存到文件夹下,再将图片的信息保存到数据库. 数据库: create table image1 ( ID ,) primary key, Im ...

  5. 通过camera + gallery android上传文件到html

    今天做项目的时候遇到一个问题:当html通过js调用input of type file时候,希望android手机的选择器可以同时出现“相机”和“图片”等,但通过下面代码 Intent i = ne ...

  6. [python小记]使用lxml修改xml文件,并遍历目录

    这次的目的是遍历目录,把目标文件及相应的目录信息更新到xml文件中.在经过痛苦的摸索之后,从python自带的ElementTree投奔向了lxml.而弃用自带的ElementTree的原因就是,na ...

  7. 日期在苹果手机上显示NaN的处理方法

    注意两点即可: 1.苹果只认识 yyyy/mmmm/dddd/  这类格式的日期 2.如果输出后还要进行处理日期对比,苹果默认会带中文字,如:年月日,需要转成上面1当中的日期格式在转时间戳进行比较 G ...

  8. CCNA2.0笔记_二层交换

    VLAN上并不需要配置IP地址,除非是出于管理的需要. 基于Vlan的设计原理,即隔离网络的广播域,再者运行STP来提供二层的防环机制:在同一个设备集中不同Vlan之间是无法通信的(在没有三层设备的情 ...

  9. JVM Specification 9th Edition (3) Chapter 2. The Structure of the Java Virtual Machine

    Chapter 2. The Structure of the Java Virtual Machine 内容列表 2.1. The class File Format (class文件的格式) 2. ...

  10. root权限NPM全局安装(-g)仍会权限不够,认识下参数 --unsafe-perm

    环境说明 ganiks@ganiks-ubuntu-trusty-64:/ganiks/parse-server$ npm -v 6.5.0 ganiks@ganiks-ubuntu-trusty-6 ...