문제 설명 주어진 N×N 크기의 그리드에서, 각 칸은 빨간색(R), 초록색(G), 파란색(B) 중 하나로 색칠되어 있다. 이 그리드에서 같은 색상의 칸들이 상하좌우로 인접하면 같은 구역을 이루게 된다. 문제는 적록색약인 사람과 그렇지 않은 사람이 봤을 때 구역의 수를 계산하는 것이다. 적록색약인 사람은 빨간색과 초록색의 차이를 거의 느끼지 못하므로 빨간색과 초록색을 같은 색상으로 본다. 적록색약이 아닌 사람은 각 색상을 구분하여 구역을 나눈다. 따라서 문제는 두 가지 경우의 구역 수를 계산해야 한다. 1. 적록색약이 아닌 사람의 구역 수 계산 : 일반적으로 각 칸에 대해 상하좌우로 연결된 같은 색을 하나의 구역으로 본다. -> 이를 구하기 위해 BFS 또는 DFS 알고리즘을 활용하여 연결된 칸들을 탐색하고, 구역의 수를 센다. 2. 적록색약인 사람의 구역 수 계산 : 적록색약인 사람은 빨간색과 초록색을 구분하지 않으므로, 빨간색과 초록색을 동일한 색으로 취급한다. -> 빨간색과 초록색을 같은 색으로 변경한 후, 다시 BFS 또는 DFS를 활용하여 구역을 센다.

import java.util.Scanner;

public class Main {
    static int N;
    static char[][] grid;
    static boolean[][] visited;

    // 4방향으로 상하좌우 탐색
    static int[] dx = {-1, 1, 0, 0};
    static int[] dy = {0, 0, -1, 1};

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        N = sc.nextInt();
        grid = new char[N][N];
        visited = new boolean[N][N];
        
        // 그리드 입력 받기
        sc.nextLine();  // 개행 문자 처리
        for (int i = 0; i < N; i++) {
            grid[i] = sc.nextLine().toCharArray();
        }

        // 적록색약이 아닌 사람의 구역 수 구하기
        int normalRegions = countRegions(false);
        
        // 적록색약인 사람의 구역 수 구하기
        int colorBlindRegions = countRegions(true);

        System.out.println(normalRegions + " " + colorBlindRegions);
        sc.close();
    }

    // 구역을 세는 함수
    public static int countRegions(boolean isColorBlind) {
        visited = new boolean[N][N];  // 방문 기록 초기화
        int regionCount = 0;

        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (!visited[i][j]) {
                    regionCount++;
                    dfs(i, j, grid[i][j], isColorBlind);  // DFS 호출
                }
            }
        }

        return regionCount;
    }

    // DFS 탐색 함수
    public static void dfs(int x, int y, char color, boolean isColorBlind) {
        visited[x][y] = true;

        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];

            if (nx >= 0 && ny >= 0 && nx < N && ny < N && !visited[nx][ny]) {
                // 적록색약인 경우, 빨강과 초록을 동일하게 취급
                if (isColorBlind) {
                    if ((color == 'R' || color == 'G') && (grid[nx][ny] == 'R' || grid[nx][ny] == 'G')) {
                        dfs(nx, ny, color, isColorBlind);
                    } else if (color == grid[nx][ny]) {
                        dfs(nx, ny, color, isColorBlind);
                    }
                } else {
                    // 적록색약이 아닌 경우, 색상이 같으면 이어진 구역으로 탐색
                    if (color == grid[nx][ny]) {
                        dfs(nx, ny, color, isColorBlind);
                    }
                }
            }
        }
    }
}

풀이 설명 - 입력 받기 : 첫째 줄에서 N을 입력받고, N×N 그리드에서 각 칸의 색을 입력받았다. - 구역 세기 : countRegions 함수는 DFS(깊이 우선 탐색)를 사용하여 구역을 세는 함수이다. isColorBlind가 true일 경우, 빨간색과 초록색을 같은 색으로 취급하여 구역을 세고, 그렇지 않으면 색상에 맞춰 구역을 센다. - DFS 탐색 : dfs 함수는 주어진 칸을 시작으로 상하좌우를 탐색하며 연결된 같은 색의 칸들을 방문 처리하고, 하나의 구역을 완성한다. 적록색약인 경우 빨간색과 초록색을 동일시하여 탐색한다. - 결과 출력 : 적록색약이 아닌 사람과 적록색약인 사람이 봤을 때의 구역 수를 각각 계산하여 출력한다. 정리 적록색약이 아닌 사람은 각 색상을 구분하여 구역을 세고, 적록색약인 사람은 빨간색과 초록색을 구분하지 않으므로 두 가지 경우의 구역 수를 계산하여 출력했다. 이 문제는 DFS 또는 BFS를 이용한 전형적인 탐색 문제로, 색상을 구분할 때 조건을 어떻게 처리하느냐에 따라 풀이가 달라진다.