你有一张某海域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;
}