标题:全球变暖
【题目描述】
你有一张某海域NxN像素的照片,"."表示海洋、"#"表示陆地,如下所示:
.......
.##....
.##....
....##.
..####.
...###.
.......
其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有2座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。
具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
.......
.......
.......
.......
....#..
.......
.......
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
【输入格式】
第一行包含一个整数N。 (1 <= N <= 1000)
以下N行N列代表一张海域照片。
照片保证第1行、第1列、第N行、第N列的像素都是海洋。
【输出格式】
一个整数表示答案。
【样例输入】
7
.......
.##....
.##....
....##.
..####.
...###.
.......
【样例输出】
1
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
问题分析:基本想法是用dfs搜索每一个岛屿,在搜索的同时判断这个岛屿中有没有陆地不会被淹没,如果没有结果就加1(注意结果要求的是被淹没陆地的数量)
判断岛屿的方法是枚举每一个像素,如果是陆地则深度搜索与之相连的陆地,属于同一个岛屿的陆地在visit中被标以相同的数值
如果一块陆地在淹没后仍然是陆地,那么在淹没前它的上下左右四个方向上应该都是陆地。
仍有疑问的地方是岛屿的定义是什么。按照我的程序的方法,有多块陆地相连即为岛屿。例如
..........
.####.....
..##......
..........
..........
..........
..##....#.
..##....#.
........#.
..........
这个样例的岛屿数目为3,且都会被淹没
如果按照题干说法“上下左右四个方向上连在一起的一片陆地组成一座岛屿”,那么上述样例中应该只有2个岛屿且都会被淹没。
遗憾的是我还没找到与后者对应的编写方法。
以下代码仅仅是自己编写的,找不到OJ测试所以也不知道对不对。如果有知道可以测真题的OJ的朋友,希望可以给我推荐一下,感谢!
#include <iostream>
#include <cstring>
#include <set>
using namespace std;
const int MAX = 1000+10;
char p[MAX][MAX];
char copy[MAX][MAX];
int visit[MAX][MAX];
int n;
int landbefore = 0;
int res = 0;
bool iflive;
void dfs(int i,int j){
if(visit[i][j] != 0)
return;
if(i<1 || j<1 || i>n || j>n)
return;
if(p[i][j] == '#'){
visit[i][j] = landbefore;
//如果当前正在深搜的岛屿中有陆地不会被淹没就把标记置为true
if(p[i-1][j] == '#' && p[i+1][j] == '#'&& p[i][j-1] == '#' && p[i][j+1] == '#')
iflive = true;
dfs(i-1,j);
dfs(i+1,j);
dfs(i,j-1);
dfs(i,j+1);
}
}
int main(){
cin >> n;
for(int i = 1;i<=n;i++)
for(int j = 1;j<=n;j++)
cin >> p[i][j];
memset(visit,0,sizeof(visit));
int pc = 0;
for(int i = 1;i<=n;i++)
for(int j = 1;j<=n;j++){
if(p[i][j] == '#'){
if(visit[i][j] == 0){
iflive = false;
landbefore++;
dfs(i,j);
//标记仍未false说明这块岛屿没有剩下的,也就是被淹没了
if(!iflive)
res++;
}
}
}
cout << res << endl;
return 0;
}