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 }