CF679C(Bear and Square Grid) 经典好题

Posted Kurokey

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF679C(Bear and Square Grid) 经典好题相关的知识,希望对你有一定的参考价值。

题目链接:传送门

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

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

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

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

      

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <cstring>
 7 #include <stack>
 8 #include <cctype>
 9 #include <queue>
10 #include <string>
11 #include <vector>
12 #include <set>
13 #include <map>
14 #include <climits>
15 #define lson root<<1,l,mid
16 #define rson root<<1|1,mid+1,r
17 #define fi first
18 #define se second
19 #define ping(x,y) ((x-y)*(x-y))
20 #define mst(x,y) memset(x,y,sizeof(x))
21 #define mcp(x,y) memcpy(x,y,sizeof(y))
22 using namespace std;
23 #define gamma 0.5772156649015328606065120
24 #define MOD 1000000007
25 #define inf 0x3f3f3f3f
26 #define N 100005
27 #define maxn 20005
28 typedef pair<int,int> PII;
29 
30 int n,k,ans,all,cnt,temp;
31 char pic[505][505];
32 int vis[505][505];
33 int color[250050]; ///子块所含 "." 的数目
34 int sum[505][505]; ///二维前缀和,避免一个点重复计数
35 int vi[250050];    ///标记数组,记录联通块是否计数过
36 
37 void dfs(int x,int y){
38     ++temp;
39     vis[x][y]=cnt;
40     if(pic[x-1][y]==.&&!vis[x-1][y])dfs(x-1,y);
41     if(pic[x+1][y]==.&&!vis[x+1][y])dfs(x+1,y);
42     if(pic[x][y-1]==.&&!vis[x][y-1])dfs(x,y-1);
43     if(pic[x][y+1]==.&&!vis[x][y+1])dfs(x,y+1);
44 }
45 inline void del(int x,int y){  ///删点
46     if(!vis[x][y])return;
47     int t=vis[x][y];
48     --vi[t];
49     if(!vi[t])all-=color[t];
50 }
51 inline void ins(int x,int y){  ///加点
52     if(!vis[x][y])return;
53     int t=vis[x][y];
54     if(!vi[t])all+=color[t];
55     ++vi[t];
56 }
57 inline int clac(int x,int y){
58     return sum[x+k-1][y+k-1]-sum[x+k-1][y-1]-sum[x-1][y+k-1]+sum[x-1][y-1];
59 }
60 int main(){
61     int i,j,group;
62     scanf("%d%d",&n,&k);
63     for(i=1;i<=n;++i){
64         scanf("%s",pic[i]+1);
65         for(j=1;j<=n;++j){
66             sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
67             if(pic[i][j]==.)++sum[i][j];
68         }    ///二维前缀和,新技能get
69     }
70     for(i=1;i<=n;++i)for(j=1;j<=n;++j)
71     if(pic[i][j]==.&&!vis[i][j]){
72         ++cnt;
73         temp=0;
74         dfs(i,j);
75         color[cnt]=temp;
76     }
77     for(i=1;i<=n-k+1;++i){
78         all=0;mst(vi,0);
79         for(j=i-1;j<=k+i;++j){
80             for(int l=1;l<=k;++l)
81                 ins(j,l);
82         }
83         for(j=i;j<i+k;++j)ins(j,k+1);
84         ans=max(ans,all+k*k-clac(i,1));
85         for(j=2;j<=n-k+1;++j){
86             for(int l=i;l<i+k;++l){
87                 del(l,j-2);
88                 ins(l,j+k);
89             }
90             del(i-1,j-1);del(i+k,j-1);
91             ins(i-1,j+k-1);ins(i+k,j+k-1);
92             ans=max(ans,all+k*k-clac(i,j));
93         }
94     }
95     printf("%d\n",ans);
96     return 0;
97 }

 

以上是关于CF679C(Bear and Square Grid) 经典好题的主要内容,如果未能解决你的问题,请参考以下文章

codeforces 356C Bear and Square Grid

codeforces 680E Bear and Square Grid 巧妙暴力

CF639F Bear and Chemistry

cf B. Bear and Compressing

CF771C Bear and Tree Jumps 题解

CF573E Bear and Bowling