标题:全球变暖
你有一张某海域NxN像素的照片,"."表示海洋、"#"表示陆地,如下所示:
.......
.##....
.##....
....##.
..####.
...###.
.......
其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有2座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
.......
.......
.......
.......
....#..
.......
.......
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
【输入格式】
第一行包含一个整数N。 (1 <= N <= 1000)
以下N行N列代表一张海域照片。
照片保证第1行、第1列、第N行、第N列的像素都是海洋。
【输出格式】
一个整数表示答案。
【输入样例】
7
.......
.##....
.##....
....##.
..####.
...###.
.......
【输出样例】
1
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。
package com.wzxy.test;
import java.util.Scanner;
/*
* 标题:全球变暖
*/
public class Main {
static Scanner sc = new Scanner(System.in);
static int N = sc.nextInt();
static String s[] = new String[N];
static char c[][] = new char[N][N];
static char copy[][] = new char[N][N];
static boolean bool1[][] = new boolean[N][N];
static boolean bool2[][] = new boolean[N][N];
static int count = 0;
static int remain = 0;
static int sum = 0;
public static void main(String[] args) {
input();
f1();
f2();
f3();
// System.out.println(" 一共有 "+count+" 个岛屿"); //一共有count个岛屿
// System.out.println("被淹没了 "+(sum=count-remain)+" 个岛屿");//被淹没了sum个岛屿
// System.out.println(" 剩余 "+remain+" 个岛屿"); //剩余remain
output();
System.out.println(sum = count - remain); // 被淹没了sum个岛屿
}
public static void input() {
for(int i=0;i<N;i++) {
s[i] = sc.next();
}
//String[] -> char[][] 一维字符串数组转换为二维字符数组
for(int i=0;i<N;i++) {
for(int j=0;j<N;j++) {
c[i][j] = s[i].charAt(j);
}
}
//c[][] -> copy[][] 将字符数组c[][]复制到copy[][]中
System.arraycopy(c, 0, copy, 0, N);
// copy = c.clone();
// copy = Arrays.copyOf(c, N);
// copy = Arrays.copyOfRange(c, 0, N);
}
public static void f1() {
//计算这片海域一共有几个岛屿
for(int i=1;i<N-1;i++) {
for(int j=1;j<N-1;j++) {
//计算方块形时的岛屿
if(c[i][j] == '#' && c[i+1][j] == '#' && c[i][j+1] == '#' && c[i+1][j+1] == '#') {
while(bool1[i][j]==false && bool1[i+1][j]==false && bool1[i][j+1]==false && bool1[i+1][j+1]==false) {
bool1[i][j] = true; bool1[i+1][j] = true; bool1[i][j+1] = true;bool1[i+1][j+1] = true;
count++;
}
}
//计算十字形的岛屿
if(c[i][j] == '#' && c[i-1][j] == '#' && c[i+1][j] == '#' && c[i][j-1] == '#' && c[i][j+1] == '#') {
while(bool1[i][j]==false && bool1[i-1][j]==false && bool1[i+1][j]==false && bool1[i][j-1]==false && bool1[i][j+1]==false) {
bool1[i][j] = true; bool1[i-1][j] = true; bool1[i+1][j] = true; bool1[i][j-1] = true; bool1[i][j+1] = true;
count++;
}
}
}
}
}
//沿海岛屿淹没演示
public static void f2() {
for(int i=1;i<N-1;i++) {
for(int j=1;j<N-1;j++) {
if(copy[i][j] == '#') {
if(copy[i-1][j] == '.' || copy[i][j-1] == '.' || copy[i+1][j] == '.' || copy[i][j+1] == '.') {
copy[i][j] = '!';
}
}
}
}
}
//寻找剩余的岛屿
public static void f3() {
for(int i=1;i<N-1;i++) {
for(int j=1;j<N-1;j++) {
if(copy[i][j] == '#') {
while(bool2[i][j]==false && bool2[i-1][j-1]==false && bool2[i-1][j]==false && bool2[i-1][j+1]==false && bool2[i][j-1]==false &&
bool2[i][j+1]==false && bool2[i+1][j-1]==false && bool2[i+1][j]==false && bool2[i+1][j+1]==false ) {
//以bool2[i][j]为中心的正方形全部为一个岛屿
bool2[i][j]=true; bool2[i-1][j-1]=true; bool2[i-1][j]=true; bool2[i-1][j+1]=true; bool2[i][j-1]=true;
bool2[i][j+1]=true; bool2[i+1][j-1]=true; bool2[i+1][j]=true; bool2[i+1][j+1]=true;
//符合条件则+1
remain++;
}
}
}
}
}
//输出copy数组
public static void output() {
for(int i=0;i<N;i++) {
for(int j=0;j<N;j++) {
System.out.print(copy[i][j]);
}System.out.println();
}
}
}
运行结果: