【题目描述】
【思路】
1、flood fill 标记该岛屿的所有陆地,同时判断该岛屿是否会被淹没
2、一个岛屿不会被淹没:该岛屿存在一块陆地四面都是陆地
TLE代码
加了一句:
boolean [][] st = new boolean[N][N];
就TLE了,算法时间复杂度不是O(n ^2)吗 为啥会超时 难道每次申请空间很耗时,有大佬解释一下吗?
import java.io.*;
public class Main{
static int N = 1010;
static int n;
static char[][] g = new char[N][N];
static char[][]backup = new char[N][N];
static int dx[] ={-1, 0, 1, 0};
static int dy[] ={0, 1, 0, -1};
static boolean isExist;
public static void dfs_num(int x, int y, boolean st[][]){
//标记为被访问过
g[x][y] = '.';
//标记为该岛屿的一块陆地
st[x][y] = true;
//是该岛屿的一块陆地且该陆地四面都是陆地
if( st[x][y] && check(x, y)) isExist = true;
for(int i = 0; i < 4; i ++){
int a = x + dx[i], b = y + dy[i];
//越界
if( a < 0 || a >= n || b < 0 || b >= n) continue;
//被访问过 或者是海洋
if(g[a][b] == '.') continue;
dfs_num(a, b, st);
}
}
//判断该岛屿是否会被淹没
public static boolean check(int x, int y){
for(int i = 0; i < 4; i ++){
int a = x + dx[i], b = y + dy[i];
if( a < 0 || a >= n || b < 0 || b >= n) continue;
if(backup[a][b] == '.') return false;
}
//四个方向都不是海洋才能保证不被淹没
return true;
}
public static void main(String args[])throws Exception{
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(bf.readLine());
for(int i = 0; i < n; i ++){
String s = bf.readLine();
g[i] = s.toCharArray();
backup[i] = s.toCharArray();
}
//被完全淹没的岛屿数
int num = 0;
for(int i = 0; i < n; i ++){
for(int j = 0; j < n; j ++)
if(g[i][j] == '#') {
boolean [][] st = new boolean[N][N];
isExist = false;
dfs_num(i, j, st);//标记完一座岛屿
if(!isExist) num ++;
}
}
System.out.println(num);
//System.out.println(check(4,4) );
}
}
AC代码
注意如果是否存在标志isExist放在dfs_num()的参数中,会在递归调用时被逐层修改导致答案错误。
import java.io.*;
public class Main{
static int N = 1010;
static int n;
static char[][] g = new char[N][N];
static char[][]backup = new char[N][N];
static int dx[] ={-1, 0, 1, 0};
static int dy[] ={0, 1, 0, -1};
static boolean isExist;
public static void dfs_num(int x, int y){
//标记为被访问过
g[x][y] = '.';
//是该岛屿的一块陆地且该陆地四面都是陆地
if(check(x, y)) isExist = true;
for(int i = 0; i < 4; i ++){
int a = x + dx[i], b = y + dy[i];
//越界
if( a < 0 || a >= n || b < 0 || b >= n) continue;
//被访问过 或者是海洋
if(g[a][b] == '.') continue;
dfs_num(a, b);
}
}
//判断该岛屿是否会被淹没
public static boolean check(int x, int y){
for(int i = 0; i < 4; i ++){
int a = x + dx[i], b = y + dy[i];
if( a < 0 || a >= n || b < 0 || b >= n) continue;
if(backup[a][b] == '.') return false;
}
//四个方向都不是海洋才能保证不被淹没
return true;
}
public static void main(String args[])throws Exception{
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(bf.readLine());
for(int i = 0; i < n; i ++){
String s = bf.readLine();
g[i] = s.toCharArray();
backup[i] = s.toCharArray();
}
//被完全淹没的岛屿数
int num = 0;
for(int i = 0; i < n; i ++){
for(int j = 0; j < n; j ++)
if(g[i][j] == '#') {
isExist = false;
dfs_num(i, j);
if(!isExist) num ++;
}
}
System.out.println(num);
//System.out.println(check(4,4) );
}
}