codeforces 680E Bear and Square Grid 巧妙暴力

这个题是个想法题

先预处理连通块,然后需要用到一种巧妙暴力,即0变1,1变0,一列列添加删除

复杂度O(n^3)

#include <cstdio>
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>
#include <map>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;
const int N=5e2+5;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
char s[N][N];
int vis[N][N],sum[N][N],now[N*N],cnt,n,k,bcc[N*N];
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};
void dfs(int x,int y){
  vis[x][y]=cnt,++bcc[cnt];
  for(int i=0;i<4;++i){
    int nx=x+dx[i],ny=y+dy[i];
    if(nx<1||nx>n||ny<1||ny>n||s[nx][ny]==‘X‘||vis[nx][ny])continue;
    dfs(nx,ny);
  }
}
int cur;
void del(int x,int y){
   if(!vis[x][y])return;
   if((--now[vis[x][y]])==0)cur-=bcc[vis[x][y]];
}
void add(int x,int y){
  if(!vis[x][y])return;
  if((++now[vis[x][y]])==1)cur+=bcc[vis[x][y]];
}
int cal(int x,int y){
  return sum[x][y]-sum[x-k][y]-sum[x][y-k]+sum[x-k][y-k];
}
int main()
{
   scanf("%d%d",&n,&k);
   for(int i=1;i<=n;++i)
    scanf("%s",s[i]+1);
   for(int i=1;i<=n;++i)
    for(int j=1;j<=n;++j){
      sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
      sum[i][j]+=s[i][j]==‘.‘?1:0;
    }
   for(int i=1;i<=n;++i)
    for(int j=1;j<=n;++j)
      if(s[i][j]==‘.‘&&!vis[i][j])++cnt,dfs(i,j);
   int ret=0;
   for(int i=1;i<=n-k+1;++i){
      cur=0,memset(now,0,sizeof(now));
      for(int p=i-1;p<=i+k;++p)
        for(int q=1;q<=k+1;++q)
           add(p,q);
      del(i-1,k+1),del(i+k,k+1);
      ret=max(ret,cur+k*k-cal(i+k-1,k));
      for(int p=2;p<=n-k+1;++p){
         for(int q=i;q<=i+k-1;++q)
           del(q,p-2),add(q,p+k);
         del(i-1,p-1);del(i+k,p-1);
         add(i-1,p+k-1);add(i+k,p+k-1);
         ret=max(ret,cur+k*k-cal(i+k-1,p+k-1));
      }
   }
   printf("%d\n",ret);
   return 0;
}

时间: 2024-08-03 22:55:22

codeforces 680E Bear and Square Grid 巧妙暴力的相关文章

codeforces 356C Bear and Square Grid

#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> using namespace std; char mp[510][510]; int vis[510][510]; int are_num[510][510]; int sum[510][510]; int

CF679C(Bear and Square Grid) 经典好题

题目链接:传送门 题目大意:给你一个n*n包含".","X"的图,你有一次机会选择一个k*k的子矩阵,将子矩阵全部变为".",问当操作过后,得到的最大联通子块包含的"."的数目是多少. 题目思路:其实这个题自己只想到了一个暴力的思路,当然TLE没商量,但实际上正确的想法就是先dfs预处理所有"."的联通块,之后的想法技巧性太强了,        操作是模拟将子矩阵右移,直接暴力会TLE,而我们可以想到实际上

codeforces679C Bear and Square Grid(dfs优化)

题意: 给你n*n的矩阵(n<=500),矩阵内有x和.,然后给你一个k 你可以把一个k*k的矩阵内全部变成. 问你最多有多少个.可以联通 思路: n^2枚举炸的位置,先预处理联通块和区间.的和 每次向右枚举只需要删掉左边一列,加上右边一列 每次枚举的区间是k*k然后扩展一圈((k+2)*(k+2))去掉四个角 这些点所在的联通块都是可以连通的 每次把这些联通块加起来,加上k*k的矩阵,减去这个矩阵内原本的.数量(预处理过) O(n^2*k) /* ***********************

Codeforces 6D Lizards and Basements 2 dfs+暴力

题目链接:点击打开链接 #include<stdio.h> #include<iostream> #include<string.h> #include<set> #include<vector> #include<map> #include<math.h> #include<queue> #include<string> #include<stdlib.h> #include<a

Codeforces 385B Bear and Strings

题目链接:Codeforces 385B Bear and Strings 记录下每一个bear的起始位置和终止位置,然后扫一遍记录下来的结构体数组,过程中用一个变量记录上一个扫过的位置,用来去重. #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int MAX_N = 5000 + 100; char str[MAX_N]; struct Node

Codeforces 451C Predict Outcome of the Game(暴力)

题目连接:Codeforces 451C Predict Outcome of the Game 题目大意:题意有点坑,就是三支球队有n场比赛,错过了k场,即这k场比赛不知道输赢,只知道第一支球队和第二支球队胜局情况差d1,第二和第三差d2,问说最后有没有可能三支队伍胜局数相同. 解题思路:考虑四种情况下的场数u,是否为3的倍数,u/3后是否比当前情况下胜局数最高的队伍大,并且还要判断该情况是否可行. #include <cstdio> #include <cstring> #in

Codeforces 385C Bear and Prime Numbers(素数预处理)

Codeforces 385C Bear and Prime Numbers 其实不是多值得记录的一道题,通过快速打素数表,再做前缀和的预处理,使查询的复杂度变为O(1). 但是,我在统计数组中元素出现个数时使用了map,以至于后面做前缀和的累加时,每次都要对map进行查询,以至于TLE.而自己一直没有发现,以为是欧拉筛对于这道题还不够优,于是上网搜题解,发现别人的做法几乎一样,但是却能跑过,挣扎了许久才想起是map的原因.map的内部实现是一颗红黑树,每次查询的复杂度为O(logN),在本来时

[Codeforces 1228E]Another Filling the Grid (排列组合+容斥原理)

[Codeforces 1228E]Another Filling the Grid (排列组合+容斥原理) 题面 一个\(n \times n\)的格子,每个格子里可以填\([1,k]\)内的整数.要保证每行每列的格子上的数最小值为1,有多少种方案 \(n \leq 250,k \leq 10^9\) 分析 这题有\(O(n^3)\)的dp做法,但个人感觉不如\(O(n^2 \log n)\)直接用数学方法求更好理解. 考虑容斥原理,枚举有\(i\)行最小值>1,有\(j\)行最小值>1,那

Codeforces Round #226 (Div. 2) C. Bear and Prime Numbers(暴力)

题目链接:点击打开链接 题意:给n个数, m次询问, 每次询问时一个区间[l, r]. 求这个区间中的所有素数,能被n个数中的几个数整除的累加和. 思路:没想到什么好办法, 直接筛出素数以后直接暴力的,没想到跑的这么快.. 最费时间的大概就是那个二重循环, 但是可能因为素数比较少, 所以实际的时间复杂度并不高. 细节参见代码: #include<cstdio> #include<cstring> #include<algorithm> #include<iostr