先bfs,预处理每块的大小,然后想象一个k*k的窗口,不断滑动,记录里面有多少堵墙,有多少个不同的连通块,计算即可
#include<iostream> #include<queue> #include<map> #include<cstdio> #include<cstring> using namespace std; const int dx[]={-1,1,0,0},dy[]={0,0,-1,1}; int stamp,n,k,ans; int a[510][510]; int mp[500*500+10],mp1[500*500+10]; inline int Max(int x,int y) { return x>y?x:y; } void bfs(int sx,int sy) { queue<int>q; int sum=1; ++stamp; q.push(sx); q.push(sy); a[sx][sy]=stamp; while(!q.empty()) { int x=q.front(); q.pop(); int y=q.front(); q.pop(); for(int i=0;i<4;i++) { int xx=x+dx[i],yy=y+dy[i]; if(!a[xx][yy]) { sum++; a[xx][yy]=stamp; q.push(xx); q.push(yy); } } } mp1[stamp]=sum; } int main() { // freopen("output.txt","r",stdin); scanf("%d%d",&n,&k); cin.ignore(); memset(a,-1,sizeof(a)); for(int i=1;i<=n;i++) { char c; for(int j=1;j<=n;j++) { c=getchar(); if(c=='.') a[i][j]=0; } c=getchar(); } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(!a[i][j]) bfs(i,j); } for(int i=k;i<=n;i++) { int tot=0,temp=0;//????? memset(mp,0,sizeof(mp)); for(int j=1;j<=k+1;j++) for(int x=i-k+1;x<=i;x++) { if(a[x][j]!=-1) { mp[a[x][j]]++; if(mp[a[x][j]]==1) temp+=mp1[a[x][j]]; } else if(j!=k+1) tot++; } for(int j=1;j<=k;j++) { if(a[i+1][j]!=-1) { mp[a[i+1][j]]++; if(mp[a[i+1][j]]==1) temp+=mp1[a[i+1][j]]; } if(a[i-k][j]!=-1) { mp[a[i-k][j]]++; if(mp[a[i-k][j]]==1) temp+=mp1[a[i-k][j]]; } } temp+=tot; ans=Max(ans,temp); temp-=tot; /* if(ans<temp) { cout<<"pos:"<<i<<" "<<k<<endl; ans=temp; cout<<"tot="<<tot<<" "<<"ans="<<ans<<endl; for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++) cout<<it->first<<endl; }*/ for(int j=k+1;j<=n;j++)//????? { // temp=0; if(a[i-k][j]!=-1) { mp[a[i-k][j]]++; if(mp[a[i-k][j]]==1) temp+=mp1[a[i-k][j]]; } if(a[i+1][j]!=-1) { mp[a[i+1][j]]++; if(mp[a[i+1][j]]==1) temp+=mp1[a[i+1][j]]; } if(a[i-k][j-k]!=-1) { mp[a[i-k][j-k]]--; if(mp[a[i-k][j-k]]==0) temp-=mp1[a[i-k][j-k]]; } // if(!mp[a[i-k][j-k]]) mp.erase(a[i-k][j-k]); if(a[i+1][j-k]!=-1) { mp[a[i+1][j-k]]--; if(mp[a[i+1][j-k]]==0) temp-=mp1[a[i+1][j-k]]; } // if(!mp[a[i+1][j-k]]) mp.erase(a[i+1][j-k]); for(int x=i-k+1;x<=i;x++)//?? { if(a[x][j-k-1]!=-1) { mp[a[x][j-k-1]]--; if(mp[a[x][j-k-1]]==0) temp-=mp1[a[x][j-k-1]]; } if(a[x][j+1]!=-1) { mp[a[x][j+1]]++; if(mp[a[x][j+1]]==1) temp+=mp1[a[x][j+1]]; } if(a[x][j]==-1) tot++; if(a[x][j-k]==-1) tot--; // if(mp[a[x][j-k-1]]==0) mp.erase(a[x][j-k-1]); } // if(i==4&&j==4) // { // cout<<tot<<endl; // cout<<temp<<endl; // cout<<"----------"<<tot+temp<<endl; // } temp+=tot; ans=Max(ans,temp); temp-=tot; // if(ans<temp) /* { ans=temp; cout<<"pos:"<<i<<" "<<j<<endl; cout<<"tot="<<tot<<" "<<"ans="<<ans<<endl; for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++) cout<<it->first<<endl; }*/ } } cout<<ans; // fclose(stdin); return 0; }