一.题意理解
此处有两点需要明确
1.海岛减少数
题目所描述的是,#块相连即是一个海岛,如果海岛的所有块都消失则该海岛消失。(一定要反复读题,因为我就理解错了, 想着还有一个海岛分裂为两个海岛的情况)
明确了这个之后,我们的问题就会转化为,确定该海岛是否存在不会沉的块。若存在,则该海岛不会沉。
(问题解决可用dfs搜索的时候,标记每个海岛是否存在这样的点,最后用总数减去沉岛屿的个数就是减少数。或者每次dfs,用flag标记,如果不存在这样的点就减少数++)
2.边界问题
我之所以说这个问题也是因为我没好好读题,因为题目中明确地图边界都是海。但没看见的应该不止我一个。但既然想到了就解决一下。
/*example
###
.#.
… 我们就定义这种情况该岛屿是有一个不会沉的点的
*/
// check 数组返回true代表该点不会沉
bool check(int x, int y) {
if (x-1>=0 && maps[x-1][y] == '.') return false;
if (x+1>=0 && maps[x+1][y] == '.') return false;
if (y-1>=0 && maps[x][y-1] == '.') return false;
if (y+1>=0 && maps[x][y+1] == '.') return false;
return true;
}
以上check数组即可解决该问题
二.题目参考代码
#include <iostream>
using namespace std;
int n;
char maps[1005][1005];
int vis[1005][1005];
// 表示每个海岛拥有不会被淹没格子的个数
int gridPerLand[1000];
int change[4][2] = {{1,0}, {-1,0}, {0,1}, {0,-1}};
/*bool check(int x, int y) {
if (x-1>=0 && maps[x-1][y] == '.') return false;
if (x+1>=0 && maps[x+1][y] == '.') return false;
if (y-1>=0 && maps[x][y-1] == '.') return false;
if (y+1>=0 && maps[x][y+1] == '.') return false;
return true;
}*/
void dfs(int x, int y, int index) {
if (x >= n || y >= n || x < 0 || y < 0 || vis[x][y] || maps[x][y] == '.') return;
vis[x][y] = 1;
//if(check(x, y)) gridPerLand[index]++;
// 题目声明最外边都是海洋,所以无需考虑边界问题直接四面判断是否都是陆地
if (maps[x-1][y] == '#' && maps[x+1][y] == '#' && maps[x][y+1] == '#' && maps[x][y-1] == '#') gridPerLand[index]++;
/*example
###
.#.
... 这种情况该岛屿是有一个不会沉的点的
*/
for (int i=0; i<4; i++) {
dfs(x + change[i][0], y + change[i][1], index);
}
}
int main() {
scanf("%d", &n);
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
cin >> maps[i][j];
}
}
int island = 0;
for(int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
if (vis[i][j] == 0 && maps[i][j] == '#') {
island++;
dfs(i, j, island);
}
}
}
int ans = 0;
// 如果该海岛没有不会沉的点(即该海岛会沉)则ans++
for (int i=1; i<=island; i++) {
if (gridPerLand[i] == 0) ans++;
}
cout << ans << endl;
return 0;
}