codeforces679C Bear and Square Grid(dfs优化)

 2023-09-05 阅读 80 评论 0

摘要:题意: 给你n*n的矩阵(n<=500),矩阵内有x和.,然后给你一个k 你可以把一个k*k的矩阵内全部变成. 问你最多有多少个.可以联通 思路: n^2枚举炸的位置,先预处理联通块和区间.的和 每次向右枚举只需要删掉左边一列,

题意:

给你n*n的矩阵(n<=500),矩阵内有x和.,然后给你一个k

你可以把一个k*k的矩阵内全部变成.

问你最多有多少个.可以联通

思路:

n^2枚举炸的位置,先预处理联通块和区间.的和

每次向右枚举只需要删掉左边一列,加上右边一列

每次枚举的区间是k*k然后扩展一圈((k+2)*(k+2))去掉四个角

这些点所在的联通块都是可以连通的

每次把这些联通块加起来,加上k*k的矩阵,减去这个矩阵内原本的.数量(预处理过)

O(n^2*k)

/* ***********************************************
Author        :devil
Created Time  :2016/6/23 15:27:25
************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
using namespace std;
const int N=510;
char s[N][N];
int sum[N][N];
int mp[N*N];
int vis[N][N];
int cur,id,all,n,k;
int vsc[N*N];
void dfs(int x,int y)
{cur++;vis[x][y]=id;if(s[x-1][y]=='.'&&!vis[x-1][y]) dfs(x-1,y);if(s[x+1][y]=='.'&&!vis[x+1][y]) dfs(x+1,y);if(s[x][y-1]=='.'&&!vis[x][y-1]) dfs(x,y-1);if(s[x][y+1]=='.'&&!vis[x][y+1]) dfs(x,y+1);
}
void push(int x,int y)
{if(!vis[x][y]) return ;if(!vsc[vis[x][y]]) all+=mp[vis[x][y]];vsc[vis[x][y]]++;
}
void pop(int x,int y)
{if(!vis[x][y]) return ;vsc[vis[x][y]]--;if(!vsc[vis[x][y]]) all-=mp[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()
{//freopen("in.txt","r",stdin);int ans=0;id=1;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][j-1]+sum[i-1][j]-sum[i-1][j-1];if(s[i][j]=='.') sum[i][j]++;}for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(s[i][j]=='.'&&!vis[i][j]){cur=0;dfs(i,j);mp[id++]=cur;}for(int i=1;i<=n-k+1;i++){all=0;memset(vsc,0,sizeof(vsc));for(int j=i-1;j<=i+k;j++)for(int l=1;l<=k;l++)push(j,l);for(int j=i;j<i+k;j++)push(j,k+1);ans=max(ans,all+k*k-cal(i+k-1,k));for(int j=1;j<=n-k;j++){for(int l=i;l<i+k;l++){pop(l,j-1);push(l,j+k+1);}pop(i-1,j);pop(i+k,j);push(i-1,j+k);push(i+k,j+k);ans=max(ans,all+k*k-cal(i+k-1,j+k));}}printf("%d\n",ans);return 0;
}

 

转载于:https://www.cnblogs.com/d-e-v-i-l/p/5610979.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/2/1080.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息