注意:岛屿完全淹没,也就是指岛屿上的每一片陆地都与海洋相连
思路:遍历每一座岛屿(连通的多片陆地)。如果遍历完某座岛屿,陆地的数量和与海洋相邻的陆地数量一致,则该岛屿会被全部淹没。(通过访问标记数组,避免重复访问)
7
.......
.##....
.##....
....##.
..####.
...###.
.......
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class TestOne {
static Scanner sc = new Scanner(System.in);
static char[][] g ; //海洋陆地的分布('#'陆地 '.'海洋)
static boolean[][] vis;//访问标记数组
static int n; //N行数据
static int ans=0; //记录被完全淹没的岛屿数量
static int[] X = {0,0,1,-1};//便于访问邻近的陆地或海洋
static int[] Y = {1,-1,0,0};
public static void main(String[] args) {
n = sc.nextInt();
g = new char[n][n];
vis = new boolean[n][n];
for(int i=0;i<n;i++) {
g[i] = sc.next().toCharArray();
}//for
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) {
if(!vis[i][j] && g[i][j]=='#') {
bfs(i,j);
}
}
}//for
System.out.println(ans);
}
//从g[i][j]开始进行广度优先遍历
private static void bfs(int x, int y) {
int cntBlock = 0;//记录对当前岛屿已遍历的陆地数量
int cntSea = 0;//记录当前岛屿中与海洋相邻的陆地数量
vis[x][y] = true; //标记为访问
Queue<Point> q = new LinkedList<Point>();//队列
q.add(new Point(x, y)); //将当前元素加入队列
while(!q.isEmpty()) {//当前队列不为空
Point now = q.poll();//弹出队列元素
cntBlock++; //陆地加1
boolean lSea=false;//记录当前出队的陆地是否与海洋相连
for(int i=0;i<4;i++) {//遍历当前陆地所有邻近的块,判断是否邻近海洋
int xx = now.x+X[i]; //邻近块的坐标
int yy = now.y+Y[i];
if(xx>=0 && xx<n && yy>=0 && yy<n) {//当前位置合法
if(g[xx][yy]=='.') {//邻近海洋
lSea = true;
}
if(g[xx][yy]=='#' && !vis[xx][yy]) {//邻近陆地并且没有访问,入队
q.add(new Point(xx, yy));
vis[xx][yy]=true;
}
}
}//for
if(lSea) {
cntSea++;
}
}//while
if(cntBlock==cntSea) {
ans++; //被淹没的岛屿数目+1
}
}
}
class Point{
int x;
int y;
public Point(int x, int y) {
super();
this.x = x;
this.y = y;
}
}