https://www.acmicpc.net/problem/2638
2638번: 치즈
첫째 줄에는 모눈종이의 크기를 나타내는 두 개의 정수 N, M (5 ≤ N, M ≤ 100)이 주어진다. 그 다음 N개의 줄에는 모눈종이 위의 격자에 치즈가 있는 부분은 1로 표시되고, 치즈가 없는 부분은 0으로
www.acmicpc.net
풀이
매 시간마다 외부 공기와 2변 이상 접촉하면 해당 위치의 치즈가 녹음
외부 공기 판별
가장자리에는 치즈가 없다. -> 모든 가장자리는 외부 공기
(0, 0)의 위치로 부터 시작 해서 치즈를 만나지 않는 위치로 dfs 탐색을 이용하여 외부 공기 판별 가능
private static void checkExternalAir(int i, int j) { visit[i][j] = true; air[i][j]=true; for (int d = 0; d < 4; d++) { int ny = i + dy[d]; int nx = j + dx[d]; if ((ny < 0 || nx < 0 || ny >= N || nx >= M) || visit[ny][nx] || cheese[ny][nx]) continue; checkExternalAir(ny, nx); } }
치즈가 녹는지 확인
모든 치즈의 위치를 확인, 현재 위치가 2변 이상 외부 공기와 접하면 List에 위치를 추가(한번에 없애기 위함)
모든 탐색이 끝난 후 List의 크기 만큼 치즈의 개수를 감소, 해당 위치의 치즈를 없앰
private static void meltingCheese() { List<Pair> meltingPos = new ArrayList<>(); for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { if (!cheese[i][j]) continue; if (isMelting(i, j)) { meltingPos.add(new Pair(i, j)); } } } for (Pair pair : meltingPos) { cheeseCnt--; cheese[pair.y][pair.x] = false; } }
전체 코드
import java.io.*; import java.util.*; public class Main { static int N, M; static boolean[][] air; static boolean[][] cheese; static boolean[][] visit; static int cheeseCnt = 0; static int[] dy = {0, 1, 0, -1}; static int[] dx = {1, 0, -1, 0}; static class Pair { public int y; public int x; Pair(int y, int x) { this.y = y; this.x = x; } } public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st; st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); M = Integer.parseInt(st.nextToken()); cheese = new boolean[N][M]; air = new boolean[N][M]; for (int i = 0; i < N; i++) { st = new StringTokenizer(br.readLine()); for (int j = 0; j < M; j++) { int temp = Integer.parseInt(st.nextToken()); if (temp == 1) { cheeseCnt++; cheese[i][j] = true; } else { cheese[i][j] = false; } } } int time = 0; while (cheeseCnt != 0) { visit = new boolean[N][M]; // 가장 자리에는 치즈가 놓이지 않는다. 즉 (0,0)과 이어지는 공기는 외부 공기 checkExternalAir(0, 0); meltingCheese(); time++; } System.out.println(time); } // dfs를 이용해 (0, 0)에서 부터 외부 공기 탐색 private static void checkExternalAir(int i, int j) { visit[i][j] = true; air[i][j]=true; for (int d = 0; d < 4; d++) { int ny = i + dy[d]; int nx = j + dx[d]; if ((ny < 0 || nx < 0 || ny >= N || nx >= M) || visit[ny][nx] || cheese[ny][nx]) continue; checkExternalAir(ny, nx); } } // 모든 위치 탐색, 치즈가 있는 장소라면 현재 시점에서 녹는 치즈인지 확인 private static void meltingCheese() { List<Pair> meltingPos = new ArrayList<>(); for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { if (!cheese[i][j]) continue; if (isMelting(i, j)) { // 외부 공기 접촉으로 녹는다면 List에 추가 meltingPos.add(new Pair(i, j)); } } } // 현재 시점에서 녹는 치즈 List 처리 for (Pair pair : meltingPos) { cheeseCnt--; cheese[pair.y][pair.x] = false; } } // 현재 위치의 치즈가 녹는지 확인 private static boolean isMelting(int i, int j) { int cnt = 0; // 인근 위치 확인 외부공기와 맞닿는 부분이 2개 이상이면 return true for (int d = 0; d < 4; d++) { int ny = i + dy[d]; int nx = j + dx[d]; if (air[ny][nx]) cnt++; if(cnt>=2){ return true; } } return false; } }
'알고리즘' 카테고리의 다른 글
BOJ 4256 - 트리(Java) (0) | 2021.12.23 |
---|---|
BOJ 23291 - 어항 정리(Java) (0) | 2021.12.22 |
ALGOSPOT - Synchronizing Clocks(JAVA) (0) | 2021.12.16 |
Programmers - 문자열 압축(Java) (0) | 2021.12.16 |
BOJ 16234 - 인구 이동(Java) (0) | 2021.12.14 |
댓글