[BOJ 2573]氷山(Java)
質問する
地球温暖化で北極氷山が溶けている.図1に示すように、氷山を2次元アレイに表示します.氷山の各部分の高さ情報は,配列された各セルに正の整数として格納される.氷山以外の海に対応する格には0が格納されている.図1では、スペースはすべてゼロで埋め込まれていると思います.
氷山の高さは海水との接触が多い場所でより速く減少するため、配列中の氷山の各部分に対応する格子の高さは毎年、格子の中で東西南北4方向に付着する0の格子の個数を減少させる.ただし、各セルに格納される高さは0より小さくなりません.海水は湖水のように氷山に囲まれているかもしれない.従って、図1の氷山は、図2に示すように1年後に変形する.
図3は、図1の氷山の2年後の変化を示す.2 D配列では,東西南北方向の格子が互いに接続されている.したがって、図2の氷山は1つであり、図3の氷山は3つに分かれている.
氷山が1つ与えられた場合、プログラムを作成して、この氷山が2つ以上分離された最初の時間(年)を求めます.図1の氷山について、答えは2です.全てが溶けるまで2つ以上離さないと、プログラムは0を出力します.
入力
1行目では、2つの整数NとMは、2次元配列の行数と列数を表すスペースで区切られます.NとMは3以上300以下である.次のN行では、各行の間にスペースがあり、M個の整数は配列の各行を表します.各グリッドの値は0以上10以下です.配列では、氷山が占める格の個数、すなわち1以上の整数が占める格の個数が10000以下である.配列の最初の行と最後の行と最後の列は常に0で埋め込まれます.
しゅつりょく
1行目は氷山分離の最初の時間(年)を出力する.氷山が溶けるまで分離していない場合は0を出力します.
方法
氷山が2つ以上になるまで時間を稼ぐ必要があります.問題の前提から見ると、氷山は一度に溶けるか、割れるか、どちらかの状態で終わる.
今から氷山を溶かしてこの場合、2つの重要な情報を格納する必要があります.
ソースコード
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
public class Iceberg {
static int n, m;
static int[][] board;
static int[][] melt;
static boolean[][] visit;
static int[] dx = new int[]{-1, 0, 1, 0};
static int[] dy = new int[]{0, 1, 0, -1};
static class Node {
int x;
int y;
public Node(int x, int y) {
this.x = x;
this.y = y;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] input = br.readLine().split(" ");
n = Integer.parseInt(input[0]);
m = Integer.parseInt(input[1]);
board = new int[n][m];
int result = 0;
for (int i = 0; i < n; i++) {
input = br.readLine().split(" ");
for (int j = 0; j < m; j++) {
board[i][j] = Integer.parseInt(input[j]);
}
}
br.close();
while (true) {
int cnt = 0;
melt = new int[n][m];
visit = new boolean[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (!visit[i][j] && board[i][j] > 0) {
visit[i][j] = true;
melting(i, j);
cnt++;
}
}
}
if (cnt == 0) {
result = 0;
break;
} else if (cnt > 1) break;
result++;
}
System.out.println(result);
}
public static void melting(int x, int y) {
ArrayDeque<Node> dq = new ArrayDeque<>();
dq.offerLast(new Node(x, y));
while (!dq.isEmpty()) {
Node now = dq.removeFirst();
int sea = 0;
for (int i = 0; i < 4; i++) {
int tmpx = now.x + dx[i];
int tmpy = now.y + dy[i];
if (!visit[tmpx][tmpy] && board[tmpx][tmpy] > 0) {
dq.offerLast(new Node(tmpx, tmpy));
visit[tmpx][tmpy] = true;
}
if (board[tmpx][tmpy] <= 0) {
sea++;
}
}
melt[now.x][now.y] = sea;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
board[i][j] -= melt[i][j];
}
}
}
}
結果
Reference
この問題について([BOJ 2573]氷山(Java)), 我々は、より多くの情報をここで見つけました https://velog.io/@wotj7687/BOJ-2573-빙산-Javaテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol