全球变暖(bfs dfs)

你有一张某海域NxN像素的照片,".“表示海洋、”#"表示陆地,如下所示:

.......
.##....
.##....
....##.
..####.
...###.
.......

其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有2座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。

例如上图中的海域未来会变成如下样子:

.......
.......
.......
.......
....#..
.......
.......

请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。

【输入格式】
第一行包含一个整数N。 (1 <= N <= 1000)
以下N行N列代表一张海域照片。

照片保证第1行、第1列、第N行、第N列的像素都是海洋。

【输出格式】
一个整数表示答案。
【输入样例】

7 
.......
.##....
.##....
....##.
..####.
...###.
.......  

【输出样例】

1

解题思路1:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
#define N 1000
char mapp[N][N];
int n,vis[N][N],dir[4][2]={{-1,0},{0,-1},{0,1},{1,0}};
struct point{
	int x,y;
	point(int a,int b){//构造方法 
		x = a;
		y = b;
	}
};
int bfs(int x,int y){
	queue<point> q;
	q.push(point(x,y));
	vis[x][y] = 1; 
	int left = 0;
	while(!q.empty()){
		point p = q.front();
		q.pop();
		int cnt = 0;
		for(int i = 0;i < 4;i++){
			int dx = p.x + dir[i][0];
			int dy = p.y + dir[i][1];
			if( mapp[dx][dy] == '#' && dx >= 0 && dx < n && dy >= 0 && dy < n){	
				cnt++;	
				if(!vis[dx][dy]){
					vis[dx][dy] = 1;
					q.push(point(dx,dy));	
				}
			} 
		}
		if(cnt == 4){
			left++;	
		}
	}
	return left;
}
int main(){
	int i,j,ans = 0;
	cin >> n;
	for(i = 0;i < n;i++){
		for(j = 0;j < n;j++)
			cin >> mapp[i][j];
	}
	memset(vis,0,sizeof(vis));
	for(i = 0;i < n;i++){
		for(j = 0;j < n;j++){
			if(mapp[i][j] == '#' && !vis[i][j]){
				if(!bfs(i,j)){ 
					ans++;
				} 
			}
		}
	}
	cout << ans << endl;
	return 0;
}

dfs
如何判断有几个岛屿?想用dfs判断,做多遍dfs。
这个思路是对的,其实我们用两个for循环搜索第一个未被访问过的#, 做dfs就好。怎么把每个岛屿记录下来?之后判断岛屿是否会被全部淹没。但是其实这个过程我们可以在找岛屿的过程中就进行判断,判断在该岛屿中是否存在一个点#,它的四周都是#

#include<iostream>
#include<cstdio>
using namespace std;
int mp[110][110];
int ans[11000];
bool vis[110][110];
void dfs(int x,int y,int k){
    if(mp[x][y] ==  '.')
        return;
    if(vis[x][y])
        return;
    vis[x][y] = 1;
    if(mp[x - 1][y] == '#'&& mp[x + 1][y] == '#'&&
    	 mp[x][y - 1] == '#' && mp[x][y + 1] == '#'){
    	ans[k]++;
    }    
    dfs(x + 1,y,k);
    dfs(x - 1,y,k);
    dfs(x,y - 1,k);
    dfs(x,y + 1,k);
}
int main(){
    int n;
    scanf("%d",&n);
    for(int i = 1;i <= n;i++){
        getchar();
        for(int j = 1;j <= n;j++){
        	scanf("%c",&mp[i][j]);
        }  
    }
    int len = 0;
    for(int i = 1;i <= n;i++){
        for(int j = 1;j <= n;j++){
            if(mp[i][j] == '#' && !vis[i][j]){
                dfs(i,j,len);
                len++;
            }
        }
    }
    int sum = 0;
    for(int i = 0;i < len;i++){
        if(ans[i] == 0){
            sum++;        	
        }
    }
    printf("%d\n",sum);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值