四叹寂寞太凄苦,闲数落花听风雨。|

IOIAK_wanguan

园龄:2年6个月粉丝:2关注:0

2022-12-27 19:51阅读: 25评论: 0推荐: 0

CodeForces-690#D1 题解

正文

很显然啊,这是在考一个叫连通块的东东,于是蒟蒻的我马上想到了连通块必备:并查集。

如果一个块四边连通了其它的块,那么合并这两个块。

当然,并查集要用二维的:

typedef pair<int,int> pii;
pii f[1005][1005];
void init(){//初始化并查集
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)
f[i][j]={i,j};
}
pii fd(pii a){//查找根
if(f[a.fi][a.sc]==a) return a;
return f[a.fi][a.sc]=fd(f[a.fi][a.sc]);
}
void unio(pii a,pii b){//合并a和b所在的集合
f[a.fi][a.sc]=fd(b);
}

最后就是查重,这里我用了手打的哈希表 set

遍历并查集数组,将每个子节点的根节点放入 set,去重,最后看 set 的元素数就可以。

struct set{
int s[1000005];
void insert(pii a){
s[a.fi*105+a.sc]++;
}
int size(){
int ret=0;
for(int &i:s)
if(i) ret++;
return ret;
}
};

最后综合:

#include<iostream>
#include<bits/stl_pair.h>
#define fi first
#define sc second
using namespace std;
typedef pair<int,int> pii;
pii f[1005][1005];
int n,m;
char a[1005][1005];
struct set{
int s[1000005];
void insert(pii a){
s[a.fi*105+a.sc]++;
}
int size(){
int ret=0;
for(int &i:s)
if(i) ret++;
return ret;
}
};
set s;
void init(){
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)
f[i][j]={i,j};
}
pii fd(pii a){
if(f[a.fi][a.sc]==a) return a;
return f[a.fi][a.sc]=fd(f[a.fi][a.sc]);
}
void unio(pii a,pii b){
f[a.fi][a.sc]=fd(b);
}
int main(){
ios::sync_with_stdio(false),cin.tie(0);
cin>>n>>m;
init();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
cin>>a[i][j];
if(a[i][j]=='.') continue;
if(a[i-1][j]=='B') unio({i-1,j},{i,j});
if(a[i+1][j]=='B') unio({i+1,j},{i,j});
if(a[i][j-1]=='B') unio({i,j-1},{i,j});
if(a[i][j+1]=='B') unio({i,j+1},{i,j});
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(a[i][j]=='B') s.insert(fd({i,j}));
cout<<s.size();
}

完结!!

后附

日志

v1.0 on 2022.12.27: 发布

本文作者:wanguan

本文链接:https://www.cnblogs.com/wanguan/p/17008864.html

版权声明:本作品采用 BY-NC-SA 4.0 许可协议进行许可。

posted @   IOIAK_wanguan  阅读(25)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起