Codeforces679C. Bear and Square Grid

n<=500,n*n的01矩阵,可以选择一个k*k的矩阵全变1,求最大1联通区域。

敢敢n^3。。模拟k*k的矩阵的位置,从左到右扫的时候,每变一个位置只会引起边界的信息变化,就记含边界的k*k矩形内的各联通块的大小以及不含边界的k*k的矩形内的0的个数,然后边移动边开个桶更新。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 #include<stdlib.h>
 5 #include<math.h>
 6 //#include<vector>
 7 //#include<iostream>
 8 using namespace std;
 9 
10 int n,K;
11 #define maxn 511
12 char mp[maxn][maxn];
13 int id[maxn][maxn];
14 
15 int ufs[maxn*maxn],size[maxn*maxn];
16 int find(int x) {return x==ufs[x]?x:(ufs[x]=find(ufs[x]));}
17 void Union(int x,int y) {x=find(x),y=find(y); if (x==y) return; size[y]+=size[x]; ufs[x]=y;}
18 
19 int bud[maxn*maxn]; bool vis[maxn][maxn];
20 int quex[maxn*maxn],quey[maxn*maxn],head,tail;
21 const int dx[]={1,-1,0,0},dy[]={0,0,1,-1};
22 void bfs(int x,int y)
23 {
24     vis[x][y]=1; int ff=id[x][y];
25     head=0; tail=1; quex[0]=x; quey[0]=y;
26     while (head!=tail)
27     {
28         const int xx=quex[head],yy=quey[head]; head++;
29         for (int i=0;i<4;i++)
30         {
31             int nx=xx+dx[i],ny=yy+dy[i];
32             if (nx<0 || nx>n || ny<0 || ny>n || vis[nx][ny] || mp[nx][ny]!='.') continue;
33             vis[nx][ny]=1; quex[tail]=nx; quey[tail]=ny; tail++;
34             int idid=id[nx][ny]; Union(idid,ff);
35         }
36     }
37 }
38 
39 void insert(int x,int y,int &tot)
40 {
41     int now=id[x][y],ff=find(now);
42     if (!bud[ff]) tot+=size[ff]; bud[ff]++;
43 }
44 void Delete(int x,int y,int &tot)
45 {
46     int now=id[x][y],ff=find(now);
47     bud[ff]--; if (!bud[ff]) tot-=size[ff];
48 }
49 int main()
50 {
51     scanf("%d%d",&n,&K);
52     for (int i=1;i<=n;i++) scanf("%s",mp[i]+1);
53     for (int i=1,tot=0;i<=n;i++)
54         for (int j=1;j<=n;j++)
55             id[i][j]=++tot;
56     for (int i=1;i<=n*n;i++) ufs[i]=i,size[i]=1;
57     
58     for (int i=1;i<=n;i++)
59         for (int j=1;j<=n;j++)
60             if (mp[i][j]=='.' && !vis[i][j]) bfs(i,j);
61     int ans=0;
62     for (int i=K;i<=n;i++)
63     {
64         memset(bud,0,sizeof(bud));
65         int tot=0,xx=0;
66         for (int j=i-K+1;j<=i;j++)
67             for (int k=1;k<=K;k++) if (mp[j][k]=='.') insert(j,k,tot);
68             else xx++;
69         if (K<n) for (int j=i-K+1;j<=i;j++) if (mp[j][K+1]=='.') insert(j,K+1,tot);
70         if (i>K) for (int k=1;k<=K;k++) if (mp[i-K][k]=='.') insert(i-K,k,tot);
71         if (i<n) for (int k=1;k<=K;k++) if (mp[i+1][k]=='.') insert(i+1,k,tot);
72         ans=max(ans,tot+xx);
73         
74         for (int k=K+1;k<=n;k++)
75         {
76             for (int j=i-K+1;j<=i;j++) xx-=(mp[j][k-K]=='X');
77             for (int j=i-K+1;j<=i;j++) xx+=(mp[j][k]=='X');
78             if (k>K+1) for (int j=i-K+1;j<=i;j++) if (mp[j][k-K-1]=='.') Delete(j,k-K-1,tot);
79             if (k<n) for (int j=i-K+1;j<=i;j++) if (mp[j][k+1]=='.') insert(j,k+1,tot);
80             if (i>K)
81             {
82                 if (mp[i-K][k]=='.') insert(i-K,k,tot);
83                 if (mp[i-K][k-K]=='.') Delete(i-K,k-K,tot);
84             }
85             if (i<n)
86             {
87                 if (mp[i+1][k]=='.') insert(i+1,k,tot);
88                 if (mp[i+1][k-K]=='.') Delete(i+1,k-K,tot);
89             }
90             ans=max(ans,tot+xx);
91 //            cout<<i<<' '<<k<<' '<<tot<<' '<<xx<<endl;
92         }
93     }
94     printf("%d
",ans);
95     return 0;
96 }
View Code
原文地址:https://www.cnblogs.com/Blue233333/p/8075902.html