全球变暖
题目分析
首先要明白这道题求啥,对于一块陆地“#”,如果它的上下左右任何一个相邻位置有还用“.”,那么这块陆地就会变成海洋。但是要注意,变成海洋后的陆地不会对周围陆地产生影响,比如下面这种情况,第二行的“#”都会被淹没变成海洋“.”,第二列和第四列的“#”都会被淹没变成海洋“.”,但是第三行第三列和第四行第三列的“#”不会被淹没。
. | . | . | . |
---|---|---|---|
. | # | # | # |
. | # | # | # |
. | # | # | # |
考虑用dfs遍历整个图。对于当前位置来说,如果他是陆地,并且之前没有被遍历过,那么就从这个地方进入dfs,这里的ans表示被完全淹没的岛屿数。flag表示当前遍历的这块岛屿有没有被淹没。flag为0表示被完全淹没了,那么ans对应加1。
int ans = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if(map[i][j] == '#' && visit[i][j] == 0) {
flag = 0;
dfs(i,j);
if(flag == 0) {
ans++;
}
}
}
}
接下来看dfs的过程,进来之后,首先把当前位置标志为已经被遍历过。遍历这个位置上下左右四个方向,如果四个方向的值都为“#”那么这个地方不会被淹没,也就意味着这个岛屿不会被淹没,flag就标记为1。然后接着去遍历这个岛屿的其它陆地。如果下一个陆地没有被遍历过,则进入继续遍历。
private static void dfs(int i, int j) {
visit[i][j] = 1;
if(map[i][j+1]=='#'&&map[i][j-1]=='#'&&map[i-1][j]=='#'&&map[i+1][j]=='#') {
flag = 1;
}
for (int k = 0; k < 4; k++) {
int x = i + nextx[k];//nextx nexty
int y = j + nexty[k];
if(visit[x][y] == 0&&map[x][y]=='#') {
dfs(x, y);
}
}
}
注意上述代码在找相邻节点的时候我没有进行越界判断,是因为我在设数组的时候给它设置了边界,即下标范围是从1~n,那么开数组的时候开大两维,即便1-1=0,也没关系,即便n+1=n+1,也不会越界。当然,你也可以按照正常大小开数组,但是如果是这样的话,一定要加上越界判断。
map = new char[n+2][n+2];
visit = new int[n+2][n+2];
for (int i = 1; i <= n; i++) {
map[i] = (" "+scanner.next()+" ").toCharArray();
}
题目代码
import java.util.Scanner;
public class Main {
static int flag=0;
static int[][] visit;
static char[][] map;
static int[] nexty = {0,-1,1,0};
static int[] nextx = {1,0,0,-1};
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
map = new char[n+2][n+2];
visit = new int[n+2][n+2];
for (int i = 1; i <= n; i++) {
map[i] = (" "+scanner.next()+" ").toCharArray();
}
int ans = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if(map[i][j] == '#' && visit[i][j] == 0) {
flag = 0;
dfs(i,j);
if(flag == 0) {
ans++;
}
}
}
}
System.out.println(ans);
}
private static void dfs(int i, int j) {
visit[i][j] = 1;
if(map[i][j+1]=='#'&&map[i][j-1]=='#'&&map[i-1][j]=='#'&&map[i+1][j]=='#') {
flag = 1;
}
for (int k = 0; k < 4; k++) {
int x = i + nextx[k];//nextx nexty
int y = j + nexty[k];
if(visit[x][y] == 0&&map[x][y]=='#') {
dfs(x, y);
}
}
}
}