백준 10026 - 적록색약 (Java)

장준혁·2024년 4월 1일

coding-test

목록 보기
2/21

🔍 문제 설명


📌 입력

첫째 줄에 N이 주어진다. (1 ≤ N ≤ 100)

둘째 줄부터 N개 줄에는 그림이 주어진다.

📌 출력

적록색약이 아닌 사람이 봤을 때의 구역의 개수와 적록색약인 사람이 봤을 때의 구역의 수를 공백으로 구분해 출력한다.


📝 코드

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {
    static int N;
    static int[] dx = {0, 1, 0, -1}; //동 남 서 북 x좌표
    static int[] dy = {1, 0, -1, 0}; //동 남 서 북 y좌표
    static char[][] paint;
    static boolean visited[][];

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        N = Integer.parseInt(br.readLine());

        paint = new char[N][N];
        visited = new boolean[N][N];


        for (int i = 0; i < N; i++) {
            String line = br.readLine();
            for (int j = 0; j < N; j++) {
                paint[i][j] = line.charAt(j);
            }
        }

        int nArea = 0;

        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (visited[i][j] == false) { //방문 상태가 false라면
                    char c = paint[i][j];
                    nArea++;
                    dfs(i, j, c);
                }
            }
        }

        for (int i = 0; i < N; i++) { //방문 배열 초기화
            Arrays.fill(visited[i], false);
        }

        int bArea = 0;

        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (visited[i][j] == false) { //방문 상태가 false
                    char c = paint[i][j];

                    bArea++;
                    if (c == 'G' || c == 'R') {
                        redGreenDfs(i, j);
                    } else {
                        dfs(i, j, c);
                    }
                }
            }
        }

        bw.write(nArea + " " + bArea + "\n");
        bw.flush();
        bw.close();
    }

    static void redGreenDfs(int x, int y) {
        visited[x][y] = true; //방문 true

        for (int i = 0; i < 4; i++) { //동 남 서 북 반복
            int nx = x + dx[i];
            int ny = y + dy[i];

            if (0 <= nx && nx < N && 0 <= ny && ny < N) { //영역 안에서 이동 여부 확인
                if (visited[nx][ny] == false && (paint[nx][ny] == 'R' || paint[nx][ny] == 'G')) {
                    //다음 이동 공간이 방문하지 않은 상태
                    //R 과 G는 동일하게 취급
                    redGreenDfs(nx, ny);
                }
            }
        }
    }

    static void dfs(int x, int y, char targetC) {
        visited[x][y] = true; //방문 true

        for (int i = 0; i < 4; i++) { //동 남 서 북 반복
            int nx = x + dx[i];
            int ny = y + dy[i];

            if (0 <= nx && nx < N && 0 <= ny && ny < N) { //영역 안에서 이동 여부 확인
                if (visited[nx][ny] == false && paint[nx][ny] == targetC) { //다음 이동 공간이 방문하지 않은 상태라면
                    dfs(nx, ny, targetC);
                }
            }
        }
    }
}

📗 정리

적록 색약과 아닌 사람이 보는 그림의 영역 개수를 체크하는 문제 였다.

Red 와 Green 을 동일 시 하고 체크하면서 진행하는 DFS 함수와 분리 하여 체크하는 DFS를 두개 만들어서 진행 했다.

굳이 이렇게 하지 않아도 2차원 배열의 R 또는 G를 통일 시켜 준후 영역을 체크 한다면 DFS를 두개 생성하지 않아도 될 것 같다는 생각이 들었다.

https://www.acmicpc.net/problem/10026

profile
wkd86591247@gmail.com

0개의 댓글