백준 치즈

KIMYEONGJUN·5일 전
post-thumbnail

문제

내가 생각했을때 문제에서 원하는부분

첫째 줄에는 모눈종이의 크기를 나타내는 두 개의 정수 N, M (5 ≤ N, M ≤ 100)이 주어진다.
그 다음 N개의 줄에는 모눈종이 위의 격자에 치즈가 있는 부분은 1로 표시되고, 치즈가 없는 부분은 0으로 표시된다.
또한, 각 0과 1은 하나의 공백으로 분리되어 있다.

출력으로는 주어진 치즈가 모두 녹아 없어지는데 걸리는 정확한 시간을 정수로 첫 줄에 출력한다.

내가 이 문제를 보고 생각해본 부분

변수 선언 및 초기화
N, M: 모눈종이의 세로, 가로 크기를 저장하는 변수이다.
cheese: 치즈 상태를 저장하는 2차원 배열로, 1은 치즈, 0은 빈 공간을 나타낸다.
outside: 외부 공기 영역을 표시하는 불리언 배열로, 외부 공기와 연결된 빈 공간에 대해 true로 표시한다.
dx, dy: 4방향(상, 하, 좌, 우) 탐색을 위한 좌표 변위 배열이다.
외부 공기 표시 함수 (markOutsideAir)
가장자리(0,0)를 시작점으로 BFS를 수행하여 치즈가 아닌 빈 칸 중 외부 공기와 연결된 부분을 모두 outside 배열에서 true로 표시한다.
이 과정을 통해 내부의 빈 공간(외부 공기와 연결되지 않은 공간)을 구분할 수 있다.
치즈 녹이기 함수 (meltCheese)
모든 치즈 칸에 대해 인접한 4칸 중 외부 공기(outside == true)와 접하는 변의 개수를 센다.
접촉 변이 2개 이상인 치즈 칸을 0으로 바꾸어 녹인 것으로 처리해준다.
만약 하나라도 치즈가 녹으면 true를 반환하고, 아니면 false로 녹을 치즈가 없음을 알린다.
메인 함수
입력 데이터를 읽어 치즈 배열을 초기화한다.
반복문에서는 매 시간마다 외부 공기 영역을 갱신하고, 치즈를 녹인다.
더 이상 녹을 치즈가 없으면 시뮬레이션을 종료하고, 걸린 시간을 출력한다.
입력 스트림을 닫아 리소스를 해제한다.

코드로 구현

package baekjoon.baekjoon_33;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

// 백준 2638번 문제
public class Main1314 {
    static int N, M;
    static int[][] cheese;
    static boolean[][] outside; // 외부 공기 표시
    static int[] dx = { -1, 1, 0, 0 };
    static int[] dy = { 0, 0, -1, 1 };

    static void markOutsideAir() {
        // 외부 공기 표시; 가장자리부터 BFS
        outside = new boolean[N][M];
        Queue<int[]> queue = new LinkedList<>();
        queue.offer(new int[] { 0, 0 });
        outside[0][0] = true;

        while (!queue.isEmpty()) {
            int[] cur = queue.poll();
            int x = cur[0], y = cur[1];
            for (int dir = 0; dir < 4; dir++) {
                int nx = x + dx[dir];
                int ny = y + dy[dir];
                if (nx >= 0 && nx < N && ny >= 0 && ny < M) {
                    if (!outside[nx][ny] && cheese[nx][ny] == 0) {
                        outside[nx][ny] = true;
                        queue.offer(new int[] { nx, ny });
                    }
                }
            }
        }
    }

    static boolean meltCheese() {
        // 녹아 없어질 치즈 위치를 계산 후 제거
        int[][] meltCount = new int[N][M];

        for (int x = 0; x < N; x++) {
            for (int y = 0; y < M; y++) {
                if (cheese[x][y] == 1) {
                    int contactCount = 0;
                    for (int dir = 0; dir < 4; dir++) {
                        int nx = x + dx[dir];
                        int ny = y + dy[dir];
                        if (nx >= 0 && nx < N && ny >= 0 && ny < M) {
                            if (outside[nx][ny]) contactCount++;
                        }
                    }
                    meltCount[x][y] = contactCount;
                }
            }
        }

        boolean meltedAny = false;
        for (int x = 0; x < N; x++) {
            for (int y = 0; y < M; y++) {
                if (cheese[x][y] == 1 && meltCount[x][y] >= 2) {
                    cheese[x][y] = 0;
                    meltedAny = true;
                }
            }
        }

        return meltedAny;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());

        cheese = new int[N][M];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < M; j++) {
                cheese[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        int time = 0;
        while (true) {
            markOutsideAir();
            boolean melted = meltCheese();
            if (!melted) break; // 더 이상 녹는 치즈 없음
            time++;
        }

        System.out.println(time);
        br.close();
    }
}

마무리

코드와 설명이 부족할수 있습니다. 코드를 보시고 문제가 있거나 코드 개선이 필요한 부분이 있다면 댓글로 말해주시면 감사한 마음으로 참고해 코드를 수정 하겠습니다.

profile
Junior backend developer

0개의 댓글