Codeforces 679 C Bear and Square Grid暴力(スライドウィンドウ)
1945 ワード
标题:n*n地図、'X'が障害、'.'周りの隣の'.'に着くことができます.
今チャンスをあげます:あるk*kサブ矩形を選んで中の'X'を'.'に変えます.
n,k<=500.最大の連通成分の中で'.'个数
暴力は変化子矩形の左上隅を列挙し、その子矩形とどのような連通成分があるかを判断する.
サブ矩形の4つの境界を調べるだけでよい.O(n^2*k)
k*kには外部に接続する連通成分がある可能性がある、まずk*kを加えてから、内部でこれらの連通成分の大きさを小さくし、繰り返し計算を防止する.スライドウィンドウの処理でよい.
今チャンスをあげます:あるk*kサブ矩形を選んで中の'X'を'.'に変えます.
n,k<=500.最大の連通成分の中で'.'个数
暴力は変化子矩形の左上隅を列挙し、その子矩形とどのような連通成分があるかを判断する.
サブ矩形の4つの境界を調べるだけでよい.O(n^2*k)
k*kには外部に接続する連通成分がある可能性がある、まずk*kを加えてから、内部でこれらの連通成分の大きさを小さくし、繰り返し計算を防止する.スライドウィンドウの処理でよい.
#include
using namespace std;
const int N=5e2+20;
int n,k;
char s[N][N],a[N][N];
int ans,cnt,vis[N][N],mk[N*N],c[N*N],pn,b[N][N];
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
void dfs(int x,int y)
{
if(!vis[x][y])
b[x][y]=pn,vis[x][y]=1,cnt++;
for(int i=0;i<4;i++)
{
int c=x+dx[i],d=y+dy[i];
if(c>=1&&c<=n&&d>=1&&d<=n&&!vis[c][d]&&a[c][d]!='X')
dfs(c,d);
}
}
int cur,res;
void init()
{
cur=1;
pn=ans=0;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(!vis[i][j]&&a[i][j]!='X')
{
++pn,cnt=0;
dfs(i,j);
c[pn]=cnt;
ans=max(cnt,ans);
}
}
}
}
void add(int x,int y,int cur)
{
int id=b[x][y];
if(id&&mk[id]!=cur)
mk[id]=cur,res+=c[id];
}
void update(int x,int y)
{
for(int i=x;i<=x+k-1;i++)
{
++c[b[i][y-1]];
--c[b[i][y+k-1]];
}
}
void solve(int x,int y)
{
res=k*k;
for(int i=y;i<=y+k-1;i++)
add(x-1,i,cur),add(x+k,i,cur);
for(int i=x;i<=x+k-1;i++)
add(i,y-1,cur),add(i,y+k,cur);
ans=max(ans,res);
}
int main()
{
while(cin>>n>>k)
{
for(int i=1;i<=n;i++)
scanf("%s",a[i]+1);
init();
for(int i=1;i+k-1<=n;i++)
{
for(int x=i;x<=i+k-1;x++)
for(int y=1;y<=k;y++)
--c[b[x][y]];
for(int j=1;j+k-1<=n;j++)
{
solve(i,j);
++cur;
if(j+k-1!=n)
update(i,j+1);
}
for(int x=i;x<=i+k-1;x++)
for(int y=n-k+1;y<=n;y++)
++c[b[x][y]];
}
printf("%d
",ans);
}
return 0;
}