| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
- 스프링부트
- 전국대학생게임개발동아리연합회
- EC2
- UNICON2023
- 체크인미팅
- 백엔드개발자
- CICD
- 티스토리챌린지
- 개발공부
- 생활코딩
- 프로그래밍
- spring ai
- bastion host
- Route53
- 라피신
- Spring boot
- NAT gateway
- 오블완
- AWS
- UNICON
- UNIDEV
- 프리티어
- openAI API
- 도커
- 인프라
- 42서울
- 게임개발동아리
- Redis
- 캡스톤디자인프로젝트
- 프롬프트엔지니어링
- Today
- Total
Hyun's Wonderwall
[백준 골드3] 2638번: 치즈 (DFS, BFS) - Java 본문
2638번: 치즈
https://www.acmicpc.net/problem/2638
문제
N×M의 모눈종이 위에 아주 얇은 치즈가 <그림 1>과 같이 표시되어 있다. 단, N 은 세로 격자의 수이고, M 은 가로 격자의 수이다. 이 치즈는 냉동 보관을 해야만 하는데 실내온도에 내어놓으면 공기와 접촉하여 천천히 녹는다. 그런데 이러한 모눈종이 모양의 치즈에서 각 치즈 격자(작 은 정사각형 모양)의 4변 중에서 적어도 2변 이상이 실내온도의 공기와 접촉한 것은 정확히 한시간만에 녹아 없어져 버린다. 따라서 아래 <그림 1> 모양과 같은 치즈(회색으로 표시된 부분)라면 C로 표시된 모든 치즈 격자는 한 시간 후에 사라진다.

<그림 2>와 같이 치즈 내부에 있는 공간은 치즈 외부 공기와 접촉하지 않는 것으로 가정한다. 그러므 로 이 공간에 접촉한 치즈 격자는 녹지 않고 C로 표시된 치즈 격자만 사라진다. 그러나 한 시간 후, 이 공간으로 외부공기가 유입되면 <그림 3>에서와 같이 C로 표시된 치즈 격자들이 사라지게 된다.
모눈종이의 맨 가장자리에는 치즈가 놓이지 않는 것으로 가정한다. 입력으로 주어진 치즈가 모두 녹아 없어지는데 걸리는 정확한 시간을 구하는 프로그램을 작성하시오.
입력
첫째 줄에는 모눈종이의 크기를 나타내는 두 개의 정수 N, M (5 ≤ N, M ≤ 100)이 주어진다. 그 다음 N개의 줄에는 모눈종이 위의 격자에 치즈가 있는 부분은 1로 표시되고, 치즈가 없는 부분은 0으로 표시된다. 또한, 각 0과 1은 하나의 공백으로 분리되어 있다.
출력
출력으로는 주어진 치즈가 모두 녹아 없어지는데 걸리는 정확한 시간을 정수로 첫 줄에 출력한다.
예제 입력 1
8 9
0 0 0 0 0 0 0 0 0
0 0 0 1 1 0 0 0 0
0 0 0 1 1 0 1 1 0
0 0 1 1 1 1 1 1 0
0 0 1 1 1 1 1 0 0
0 0 1 1 0 1 1 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
예제 출력 1
4
풀이
치즈 내부의 빈 공간은 외부 공기가 아니지만, 시간이 지나면 외부 공기와 맞닿을 수 있으므로, 매 시간마다 외부 공기 영역을 갱신해야 했다.
이를 위해 isOuterAir 배열을 만들고 meltCheese()의 매 반복마다 markOuterAir()에서 BFS를 수행해 해당 시간에서의 외부 공기 영역을 표시했다.
이후 map을 이중 for문으로 순회하며 각 치즈가 외부 공기와 2변 이상 접촉했는지를 canMelt()에서 판단해 리스트에 담고, 한번에 녹인다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
public class Main
{
static int[][] map;
static boolean[][] isOuterAir;
static int[] dx = {-1, 0, 1, 0};
static int[] dy = {0, -1, 0, 1};
static class Node {
int x, y;
public Node(int x, int y){
this.x = x;
this.y = y;
}
}
static void markOuterAir(int n, int m) {
isOuterAir = new boolean[n][m];
Queue<int[]> q = new LinkedList<>();
q.add(new int[]{0, 0});
isOuterAir[0][0] = true;
while (!q.isEmpty()) {
int[] cur = q.poll();
for (int d = 0; d < 4; d++) {
int nx = cur[0] + dx[d];
int ny = cur[1] + dy[d];
if (nx >= 0 && ny >= 0 && nx < n && ny < m) {
if (!isOuterAir[nx][ny] && map[nx][ny] == 0) {
isOuterAir[nx][ny] = true;
q.add(new int[]{nx, ny});
}
}
}
}
}
static boolean canMelt(int x, int y, int n, int m) {
int count = 0;
for (int d = 0; d < 4; d++) {
int nx = x + dx[d];
int ny = y + dy[d];
if (nx >= 0 && ny >= 0 && nx < n && ny < m) {
if (map[nx][ny] == 0 && isOuterAir[nx][ny]) {
count++;
}
}
}
return count >= 2;
}
static int meltCheese(int n, int m) {
int time = 0;
while (true) {
markOuterAir(n, m);
List<Node> toMelt = new ArrayList<>();
boolean hasCheese = false;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (map[i][j] == 1) {
hasCheese = true;
if (canMelt(i, j, n, m)) {
toMelt.add(new Node(i, j));
}
}
}
}
if (!hasCheese) break;
for (Node node : toMelt) {
map[node.x][node.y] = 0;
}
time++;
}
return time;
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] nm = br.readLine().split(" ");
int n = Integer.parseInt(nm[0]);
int m = Integer.parseInt(nm[1]);
map = new int[n][m];
for (int i = 0; i < n; i++) {
String[] line = br.readLine().split(" ");
for (int j = 0; j < m; j++) {
map[i][j] = Integer.parseInt(line[j]);
}
}
int time = meltCheese(n, m);
System.out.println(time);
}
}'Study > PS' 카테고리의 다른 글
| [백준 실버2] 11724번: 연결 요소의 개수 (DFS) - Java (2) | 2025.07.26 |
|---|---|
| [백준 골드5] 2668번: 숫자고르기 (DFS) - Java (2) | 2025.07.26 |
| [백준 골드1] 1175번: 배달 (BFS) - Java (2) | 2025.07.24 |
| [백준 골드5] 1107번: 리모컨 (브루트포스) - Java (0) | 2025.07.19 |
| [백준 골드3] 15685번: 드래곤 커브 (구현) - Java (0) | 2025.07.18 |