给你n∗n的矩阵里面有.和X,然后你可以把一块k∗k的全部变成.
问你一个连通块里最多有多少个.
看着不太难的题,但是不太好搞
首先是dfs预处理每个连通块里的.的个数
然后是n2的枚举k∗k的那块,对于k∗k这块,肯定都是.,然后就是枚举(k+2)∗(k+2)的这块的四周
去掉4个角,因为这四周和k∗k的相邻,然后看有多少个连通块,个数加进去
最后扣掉在内部的
思路感觉不难,但是不是很好实现,如何n3的枚举呢
因为如果n2的枚举顶点,再k2的枚举里面的元素,就TLE了
所以要枚举行,然后对每行的第一个k∗k的矩阵,里面的.保存
然后列里变换,只需要减去左边一列,加上右边一列,这是n3的
然后知道了变换,然后n的枚举列,n的枚举四周
但是你不知道四周的连通块里有多少在内部
所以开头枚举里面的元素的时候,就要保存在内部的元素,属于第几个连通块的有几个
然后对于每个周围连着的连通块,ans+=all[i]−in[i]
感觉最近休息太少了,这种题都写不明白了
代码:
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std;
#define MAX 505
#define MAXN 1000005
#define maxnode 205
#define sigma_size 2
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lrt rt<<1
#define rrt rt<<1|1
#define middle int m=(r+l)>>1
#define LL long long
#define ull unsigned long long
#define mem(x,v) memset(x,v,sizeof(x))
#define lowbit(x) (x&-x)
#define pii pair<int,LL>
#define bits(a) __builtin_popcount(a)
#define mk make_pair
#define limit 10000
//const int prime = 999983;
const int INF = 0x3f3f3f3f;
const LL INFF = 0x3f3f;
//const double pi = acos(-1.0);
const double inf = 1e18;
const double eps = 1e-9;
const LL mod = 1e8+9;
const ull mx = 133333331;
/*****************************************************/
inline void RI(int &x) {
char c;
while((c=getchar())<'0' || c>'9');
x=c-'0';
while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0';
}
/*****************************************************/
char s[505][505];
int dx[5]={0,1,0,-1};
int dy[5]={1,0,-1,0};
int sum[MAX*MAX];
int a[MAX][MAX];
int vis[MAX][MAX];
int vv[MAX*MAX];
int be[MAX][MAX];
int cnt[MAX*MAX];
void dfs(int x,int y,int c){
be[x][y]=c;
sum[c]++;
vis[x][y]=1;
for(int k=0;k<4;k++){
int xx=x+dx[k];
int yy=y+dy[k];
if(a[xx][yy]==1&&!vis[xx][yy]) dfs(xx,yy,c);
}
}
int main(){
int n,K;
while(cin>>n>>K){
mem(a,0);mem(vis,0);mem(sum,0);
for(int i=1;i<=n;i++){
scanf("%s",s[i]+1);
for(int j=1;j<=n;j++){
if(s[i][j]=='.') a[i][j]=1;
}
}
int c=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(a[i][j]==1&&!vis[i][j]){
c++;
dfs(i,j,c);
}
}
}
int ans=0;
mem(vv,0);
for(int i=1;i<=n-K+1;i++){
mem(cnt,0);
for(int j=i;j<i+K;j++){
for(int k=1;k<=K;k++){
if(s[j][k]=='.') cnt[be[j][k]]++;
}
}
for(int j=1;j<=n-K+1;j++){
int temp=K*K;
vector<int> tmp;
for(int k=i;k<i+K;k++){
if(a[k][j-1]){
int xx=be[k][j-1];
if(!vv[xx]){
vv[xx]=1;
tmp.push_back(xx);
}
}
if(a[k][j+K]){
int xx=be[k][j+K];
if(!vv[xx]){
vv[xx]=1;
tmp.push_back(xx);
}
}
}
for(int k=j;k<j+K;k++){
if(a[i-1][k]){
int xx=be[i-1][k];
if(!vv[xx]){
vv[xx]=1;
tmp.push_back(xx);
}
}
if(a[i+K][k]){
int xx=be[i+K][k];
if(!vv[xx]){
vv[xx]=1;
tmp.push_back(xx);
}
}
}
for(int k=0;k<tmp.size();k++){
temp+=sum[tmp[k]]-cnt[tmp[k]];
vv[tmp[k]]=0;
}
ans=max(ans,temp);
for(int k=i;k<i+K;k++){
if(a[k][j]) cnt[be[k][j]]--;
if(a[k][j+K]) cnt[be[k][j+K]]++;
}
}
}
cout<<ans<<endl;
}
return 0;
}