[BOJ 2636]チーズ(Java)
28667 ワード
質問する
下図1に示すように、正方形の格子からなる正方形の板があり、その上に薄いチーズ(灰色の部分)が置かれています.板の縁(<図1>では、四角形のXの部分)にはチーズが入っておらず、チーズには1つ以上の穴が開いていてもよい.
これらのチーズを空気中に入れると溶け、空気に触れる車両は1時間後に溶けます.チーズの穴には空気が入っていませんが、穴を囲むチーズが溶けて穴が開くと空気が穴に入ります.<図1>に示すように、チーズ孔を囲むチーズは溶けず、図2>に示すように、「c」と表記された部分だけが1時間後に溶けて消える.
あと1時間で<図2>の「c」で表される部分は<図3>に示すように溶けて消えてしまいます.
<図3>チーズが2時間後の様子で、残りの破片はあと1時間で全部溶けてしまいました.そのため、初めてチーズが全部溶けて消えるまで3時間かかります.<図3>に示すように、チーズは融解中にいくつかに分けることができる.
矩形板の大きさとチーズが板に置かれたとき、空気中のチーズがすべて溶けるのに要する時間と、すべて溶ける1時間前にチーズの破片が残った格子数を入力するプログラムを作成します.
入力
最初の行は、矩形板の縦横長が正の整数であることを示します.縦横の長さは最大100です.板上の各横線の形状は、上から下へ順に2行目から最後の行までです.チーズのない格子は0で、チーズのある格子は1で、数字の間にスペースがあります.
しゅつりょく
1行目はチーズが全部溶けて消えるまでの時間を出力し、2行目は全部溶ける1時間前に置いたチーズの破片の格子数を出力します.
方法問題の要求に従って大幅に分離した. で与えられた空間にチーズがあるかどうかを判断します.チーズがある場合は、既存のチーズの数を保存してください. チーズが溶けました. が溶けて消えた空間には空気が満ちていた.
最初の条件と2番目の条件「所定の空間にチーズが存在するかどうかを決定し、チーズの数を保存する」で、すべての場所に移動し、チーズの数を返す関数(getCheescnt()の値をlastCheeseに格納します.
2つ目の条件「チーズが溶ける」すべての場所に移動して実行します.この場所がチーズの場合、上、下、左、右の[空気](Air)の値を0に設定して溶かします.次にairDequeに位置を追加し、次の呼び出しのfillAir()から実際の空気に変換できます.
3つ目の条件は「溶けて消えた空間に空気を充填する」ことです.実施する.2つ目の条件では、融解領域が現れるたびにairDequeに位置を保存します.BFSに移動して空気を充填し、空気の実際のアレイに表示します.
上記の条件を繰り返し、チーズが消えるまで時間と最後のチーズの数を記録します.
ソースコード
下図1に示すように、正方形の格子からなる正方形の板があり、その上に薄いチーズ(灰色の部分)が置かれています.板の縁(<図1>では、四角形のXの部分)にはチーズが入っておらず、チーズには1つ以上の穴が開いていてもよい.
これらのチーズを空気中に入れると溶け、空気に触れる車両は1時間後に溶けます.チーズの穴には空気が入っていませんが、穴を囲むチーズが溶けて穴が開くと空気が穴に入ります.<図1>に示すように、チーズ孔を囲むチーズは溶けず、図2>に示すように、「c」と表記された部分だけが1時間後に溶けて消える.
あと1時間で<図2>の「c」で表される部分は<図3>に示すように溶けて消えてしまいます.
<図3>チーズが2時間後の様子で、残りの破片はあと1時間で全部溶けてしまいました.そのため、初めてチーズが全部溶けて消えるまで3時間かかります.<図3>に示すように、チーズは融解中にいくつかに分けることができる.
矩形板の大きさとチーズが板に置かれたとき、空気中のチーズがすべて溶けるのに要する時間と、すべて溶ける1時間前にチーズの破片が残った格子数を入力するプログラムを作成します.
入力
最初の行は、矩形板の縦横長が正の整数であることを示します.縦横の長さは最大100です.板上の各横線の形状は、上から下へ順に2行目から最後の行までです.チーズのない格子は0で、チーズのある格子は1で、数字の間にスペースがあります.
しゅつりょく
1行目はチーズが全部溶けて消えるまでの時間を出力し、2行目は全部溶ける1時間前に置いたチーズの破片の格子数を出力します.
方法
最初の条件と2番目の条件「所定の空間にチーズが存在するかどうかを決定し、チーズの数を保存する」で、すべての場所に移動し、チーズの数を返す関数(getCheescnt()の値をlastCheeseに格納します.
2つ目の条件「チーズが溶ける」すべての場所に移動して実行します.この場所がチーズの場合、上、下、左、右の[空気](Air)の値を0に設定して溶かします.次にairDequeに位置を追加し、次の呼び出しのfillAir()から実際の空気に変換できます.
3つ目の条件は「溶けて消えた空間に空気を充填する」ことです.実施する.2つ目の条件では、融解領域が現れるたびにairDequeに位置を保存します.BFSに移動して空気を充填し、空気の実際のアレイに表示します.
上記の条件を繰り返し、チーズが消えるまで時間と最後のチーズの数を記録します.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
public class Cheese_2636 {
static int n, m;
static int[][] board;
static boolean[][] air;
static int[] dx = new int[]{-1, 0, 1, 0};
static int[] dy = new int[]{0, 1, 0, -1};
static ArrayDeque<Node> airDeque = new ArrayDeque<>();
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));
StringBuilder sb = new StringBuilder();
String[] input = br.readLine().split(" ");
n = Integer.parseInt(input[0]);
m = Integer.parseInt(input[1]);
board = new int[n][m];
air = new boolean[n][m];
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]);
}
}
// air 배열의 초기 구역 입력
airDeque.offerLast(new Node(0, 0));
fillAir();
int time = 0;
int lastCheese = 0;
int cheese;
// 치즈가 0개가 될 때 까지 순차적으로 진행합니다.
// 1. lastCheese 에 현재 board에 있는 모든 치즈의 개수를 저장합니다.
// 2. cheeseMelt() 를 호출해 치즈를 녹입니다.
// 3. fillAir() 를 호출해 공기를 채웁니다.
// 4. time++ 로 지나온 시간을 추가합니다.
while ((cheese = getCheeseCnt()) > 0) {
lastCheese = cheese;
cheeseMelt();
fillAir();
time++;
}
sb.append(time).append('\n').append(lastCheese);
System.out.println(sb);
br.close();
}
// 치즈가 남아있는지 확인합니다. while 문의 종료 조건을 담당합니다.
// 마지막으로 남은 치즈를 카운팅 하기 위해 int형을 반환합니다.
public static int getCheeseCnt() {
int cheese = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (board[i][j] == 1) cheese++;
}
}
return cheese;
}
// 모든 노드들을 개별 탐색하며 치즈를 녹입니다.
// isMelted() 함수로 치즈가 녹을 수 있는지 판단하고 녹게되면 airDeque()를 호출해 공기로 변환합니다.
public static void cheeseMelt() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (board[i][j] == 1 && isMelted(i, j)) {
board[i][j] = 0;
airDeque.offerLast(new Node(i, j));
}
}
}
}
// 공기를 채우는 함수, airDeque에 있는 값으로 BFS를 돌려 공기를 채워간다.
public static void fillAir() {
while (!airDeque.isEmpty()) {
Node now = airDeque.removeFirst();
air[now.x][now.y] = true;
for (int i = 0; i < 4; i++) {
int tmpx = now.x + dx[i];
int tmpy = now.y + dy[i];
if (0 <= tmpx && tmpx < n && 0 <= tmpy && tmpy < m && !air[tmpx][tmpy] && board[tmpx][tmpy] == 0) {
air[tmpx][tmpy] = true;
airDeque.offerLast(new Node(tmpx, tmpy));
}
}
}
}
// 선택된 위치의 치즈가 녹는 치즈이면 true, 녹지 않는 치즈이면 false를 반환
public static boolean isMelted(int x, int y) {
boolean melt = false;
for (int i = 0; i < 4; i++) {
int tmpx = x + dx[i];
int tmpy = y + dy[i];
if (air[tmpx][tmpy]) {
melt = true;
break;
}
}
return melt;
}
}
結果Reference
この問題について([BOJ 2636]チーズ(Java)), 我々は、より多くの情報をここで見つけました https://velog.io/@wotj7687/BOJ-2636-치즈-Javaテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol