标签:
这个题是个想法题
先预处理连通块,然后需要用到一种巧妙暴力,即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; }
codeforces 680E Bear and Square Grid 巧妙暴力
标签:
原文地址:http://www.cnblogs.com/shuguangzw/p/5608696.html