全球变暖
你有一张某海域 N×N 像素的照片,”.”表示海洋、”#”表示陆地,如下所示:
.......
.##....
.##....
....##.
..####.
...###.
.......
其中”上下左右”四个方向上连在一起的一片陆地组成一座岛屿,例如上图就有 2 座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。
具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
.......
.......
.......
.......
....#..
.......
.......
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
输入格式
第一行包含一个整数N。
以下 N 行 N 列,包含一个由字符”#”和”.”构成的 N×N 字符矩阵,代表一张海域照片,”#”表示陆地,”.”表示海洋。
照片保证第 1 行、第 1 列、第 N 行、第 N 列的像素都是海洋。
输出格式
一个整数表示答案。
数据范围
1≤N≤1000
输入样例1:
7
.......
.##....
.##....
....##.
..####.
...###.
.......
输出样例1:
1
输入样例2:
9
.........
.##.##...
.#####...
.##.##...
.........
.##.#....
.#.###...
.#..#....
.........
输出样例2:
1
分析:我们来简单看下题目,它的意思是要我们去求被完全淹没岛屿的数量,那么我们就按它的题目意思来,我们在利用bfs的时候检验连通性的时候分别统计扫到的陆地的数目和在这片岛屿中会被淹没的陆地的数量,如果最后两者相等那么说明这个岛屿会给整个淹没那么我们应该怎么统计被淹没的陆地数目呢?其实很简单:就是当我们进行上下左右遍历的时候如果扫到了海洋(也就是这里的‘.’)我们就做个标记说明我们向四周扩散的这个点是会被淹没的,这一题也比较简单,大家可以看下代码应该马上就能懂了!!!
代码:
#include<iostream>
#include<queue>
#define x first
#define y second
using namespace std;
typedef pair<int, int>PII;
const int N = 1010;
int n;
char c[N][N];
bool st[N][N];
queue<PII>qq;
int cnt = 0;//记录原来有多少个岛屿会被完全淹没
int dx[] = { -1,0,1,0 };
int dy[] = { 0,1,0,-1 };
void bfs(int x, int y,int&sum,int&bound) {
st[x][y] = true;
qq.push({ x,y });
while (!qq.empty()) {
bool is_bound = false;
PII t = qq.front();
sum++;
qq.pop();
for (int i = 0; i < 4; i++) {
int a = dx[i] + t.x;
int b = dy[i] + t.y;
if (a < 0 || a >= n || b < 0 || b >= n)continue;
if (st[a][b] == true)continue;//遍历过的陆地
if (c[a][b] == '.') {
is_bound = true;
continue;
}
st[a][b] = true;
qq.push({ a,b });
}
if (is_bound == true)bound++;//当前向四周扩散的点t是会被淹没的
}
}
int main() {
cin >> n;
for (int i = 0; i < n; i++) {
cin >> c[i];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (!st[i][j] && c[i][j] == '#') {
int sum = 0, bound = 0;
bfs(i, j, sum, bound);
if (sum == bound)cnt++;
}
}
}
cout << cnt << endl;
return 0;
}
运行结果: