반응형
01-15 01:04
Today
Total
«   2025/01   »
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 29 30 31
관리 메뉴

개발하는 고라니

[백준] 2638번 : 치즈 본문

Programming/백준

[백준] 2638번 : 치즈

조용한고라니 2021. 2. 12. 15:14
반응형
 

2638번: 치즈

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

www.acmicpc.net


[BFS]

이전에 만났던 '백조의 호수', '탈출' 같은 문제처럼 2개의 BFS를 필요로 한다. 다만 이 문제는 치즈 내부에 공기가 차있을 경우 치즈 외부의 공기와 동일한 역할을 하지 못한다. 즉 치즈를 녹일 수 있는 조건에 영향을 미치지 못하기에 이것이 조금 까다로웠다. 그래서 airBFS라는 메서드를 실행할 때 마다, (0, 0)에서 공기를 퍼지게 하는 느낌으로 (0, 0)에서 BFS를 실행해 치즈를 만나면 숫자를 증가시켜 공기와 2번 이상 접촉한 치즈를 선별하는 과정으로 설정했다.

 

그 다음 cheeseBFS라는 메서드에서 외부 공기와 2번 이상 접촉한 치즈를 녹였다.

 

# Code </>

public class Main {

    static class Point{
        int y, x;
        public Point(int yy, int xx){
            y=yy;
            x=xx;
        }
    }
    static final int N = 101;
    static int n, m;
    static boolean flag;

    static int[][] map = new int[N][N];
    static int[][] state = new int[N][N];
    static boolean[][] visit = new boolean[N][N];

    static int[] Y = {-1, 1, 0, 0}, X = {0, 0, -1, 1};

    static boolean airBFS(){
        Queue<Point> Q = new LinkedList<>();
        visit[0][0] = true;
        Q.add(new Point(0,0));

        while(!Q.isEmpty()){
            Point p = Q.poll();
            int y = p.y;
            int x = p.x;

            for(int a=0; a<4; a++){
                int ny = y+Y[a];
                int nx = x+X[a];

                if(ny < 0 || nx < 0 || ny > n || nx > m) continue;

                if(map[ny][nx] == 0 && !visit[ny][nx]){ //공기이고, 방문하지 않았으면
                    visit[ny][nx] = true;
                    Q.add(new Point(ny, nx));
                }

                if(map[ny][nx] == 1) { //치즈이면
                    flag = true; //녹일 치즈가 한 칸이라도 존재하면 true, 치즈가 다 녹았다면 false를 유지한다
                    state[ny][nx]++; //state[ny][nx] >= 2 이면 cheeseBFS에서 녹게된다.
                }
            }
        }
        return flag;
    }

    static void cheeseBFS(){

        Queue<Point> Q = new LinkedList<>();

        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++){
                if(state[i][j] > 1 && !visit[i][j]){
                    map[i][j] = 0;
                    visit[i][j] = true;
                    Q.add(new Point(i, j));
                }

                while(!Q.isEmpty()){
                    Point p = Q.poll();
                    int y = p.y;
                    int x = p.x;

                    for(int a=0; a<4; a++) {
                        int ny = y + Y[a];
                        int nx = x + X[a];

                        if (ny < 0 || nx < 0 || ny > n || nx > m || visit[ny][nx]) continue;

                        if(state[ny][nx] > 1) {
                            visit[ny][nx] = true;
                            map[ny][nx] = 0;
                            Q.add(new Point(ny, nx));
                        }
                    }
                }
            }
    }

    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());

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

        int time = 0;
        while(true){
            /* init */
            visit = new boolean[N][N];
            state = new int[N][N];
            flag = false;
            /* init */

            if(!airBFS()) break;

            time++;
            visit = new boolean[N][N];

            cheeseBFS();
        }

        System.out.println(time);
    }
}
반응형

'Programming > 백준' 카테고리의 다른 글

[백준] 9376번 : 탈옥  (0) 2021.02.13
[백준] 1774번 : 우주신과의 교감  (0) 2021.02.12
[백준] 1167번 : 트리의 지름  (0) 2021.02.10
[백준] 16234번 : 인구 이동  (0) 2021.02.09
[백준] 1325번 : 효율적인 해킹  (0) 2021.02.09
Comments