蓝桥:全球变暖

BFS

#include<bits/stdc++.h>
#define PII pair<int,int>
using namespace std;
const int N=1005;
char a[N][N];
int v[N][N];
int dx[]={1,0,-1,0};
int dy[]={0,-1,0,1};
int n;
bool check(int x,int y){
	queue<PII> q;
	q.push({x,y});
	v[x][y]=1;
	int flag=0;
	while(q.size()){
		PII t=q.front();q.pop();
		
		if(!flag){//搜索有一个#周围有几个#,有四个就不会被淹没 
			int temp=0;
			for(int i=0;i<4;i++){
				int tx=t.first+dx[i];int ty=t.second+dy[i];
				if(tx<1 || tx>n ||ty<1 ||ty>n){//搜索到边界以外,也算是# 
					temp++;	continue;
				}
				if(a[tx][ty]=='#')	{
					temp++;	continue;
				}
			}
			if(temp==4)	flag=1;
		}
		
		for(int k=0;k<4;k++){//标记一个连通块为一个岛屿 
			int tx=t.first+dx[k];int ty=t.second+dy[k];
			if(tx<1 || tx>n ||ty<1 ||ty>n)	continue;
			if(v[tx][ty]==1)	continue;
			if(a[tx][ty]=='.')	continue;
			q.push({tx,ty});
			v[tx][ty]=1;
		}
	
	}
		return flag==1;
}

int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cin>>a[i][j];
		}
	}
	int cnt1=0,cnt2=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(a[i][j]=='#' && v[i][j]==0 ){//如果是#,则bfs,将周围的#都标记为已访问 ,所以每个连通块只数一次 
				if(check(i,j))	cnt1++;//check检查有几个岛屿没有淹没 
				cnt2++;	//返回有几个岛屿,									
			}			
		}
	}
	cout <<cnt2-cnt1<<endl;
	return 0;
}

DFS

#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
const int N=1005;
char a[N][N];

int n;
int cnt1,cnt2;//cnt1是不会被淹没的点,cnt2是岛屿数量
int dx[]={1,0,-1,0};
int dy[]={0,-1,0,1};
bool ym;//1是不会被淹没,对于不会被淹没的点只计算一次,避免在一个dfs循环中重复
void dfs(int x,int y){
		if(ym==0){//如果不会被淹没,才遍历,避免重复
			int temp=0;
			for(int i=0;i<4;i++){
				int tx=x+dx[i];
				int ty=y+dy[i];
				if(a[tx][ty]!='.')	temp++;
			}
			if(temp==4)	cnt1++,ym=1;
		}
	
	a[x][y]='*';//将搜索过的点标记为其他符号,用于计算岛屿个数
	for(int i=0;i<4;i++){
		int tx=x+dx[i];
		int ty=y+dy[i];
		if(a[tx][ty]=='#'&& tx>=1&&tx<=n && ty>=1 && ty<=n){
			dfs(tx,ty);
		}
	}
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cin>>a[i][j];
		}
	}
	
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(a[i][j]=='#'){
				cnt2++;
				ym=0;
				dfs(i,j);
			}	
			
		}
	}
	cout<<cnt2-cnt1<<endl;
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值