知识点:dfs
很明显的连通块
em……转载于P1506 拯救oibh总部题解 - qianyangyi 的博客 - 洛谷博客 (luogu.com.cn)
(搞得好像很多人看一样
思路:每遇到一个没有访问过的点,就进行dfs,如果是重要区域cnt++,是围墙return,是边界则说明围墙不封闭,则本次dfs的cnt清零。
看起来挺简单的,细节比较多,多注意
#include <iostream>
#include <cstring>//memset头文件
using namespace std;
int a[505][505],cnt;
bool ct;
void dfs(int x,int y){
if(a[x][y]==0) return;//围墙或访问过的清零
if(a[x][y]==-1){//dfs到说明围墙不封闭
ct=1;//标记,本次cnt作废
return;
}
cnt++;
a[x][y]=0;//避免二次访问
dfs(x+1,y);//四个方向
dfs(x,y+1);
dfs(x-1,y);
dfs(x,y-1);
return;
}
int main(){
int n,m;
cin>>n>>m;
char c;
memset(a,-1,sizeof(a));
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>c;//这里也可以不转换,直接char a[500][500];
if(c=='0') a[i][j]=1;
else if(c=='*') a[i][j]=0;
}
}
int ans=0;//答案
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]==1){
cnt=ct=0;//每次计数器和判断器清零,防止被上组数据影响
dfs(i,j);//dfs
if(ct!=1) ans+=cnt;//如果围墙是封闭的,则cnt加入ans里
}
}
}
cout<<ans<<endl;//输出
return 0;
} //完结撒花
本蒟蒻写题解不易 给个赞不过分吧qwq