알고리즘

백준10026_적록색약 (java)

lamp_jiny 2021. 11. 11. 23:25

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

 

10026번: 적록색약

적록색약은 빨간색과 초록색의 차이를 거의 느끼지 못한다. 따라서, 적록색약인 사람이 보는 그림은 아닌 사람이 보는 그림과는 좀 다를 수 있다. 크기가 N×N인 그리드의 각 칸에 R(빨강), G(초록)

www.acmicpc.net

예제 입력 1

5
RRRBB
GGBBB
BBBRR
BBRRR
RRRRR

예제 출력 1

4 3

문제 풀이 방식

  • 길찾기 문제처럼 첫 (0,0)부터 방문체크를 하면서 같은 상하좌우에서 같은 색깔이 하나라도 있으면 같은 구역으로 본다. 요소 수 찾기 문제랑 비슷했다.
  • 적록색약이 아닌 사람이 보는 구역의 수는 DFS함수를 돌며 색깔이 같을동안 탐색해준다. 색상이 다르면 함수를 종료하고 count+1해준다.
  • 그렇다면 적록색약이 아닌사람은?...
  • 처음에 그리드의 값을 받을 때 G값을 R로 변경해주면 되지 않을까??
  • 그래도 잘 모르겠으니 블로그 검색!
  • 찾아보니 나처럼 생각한 사람도 있고, 아예 색약인 사람과 색약이 아닌 사람의 dfs를 따로 만들어줘서 푼사람도 있었다. 나는 visited배열을 하나만 사용해서 중간에 Arrays.fill을 사용해 초기화 후 다시 사용했고, 또 어떤 사람은 visited배열도 2개 따로 만들어 준 사람도 있었다.
  • 문제는 어렵지 않았으나, 아직 dfs와 bfs가 익숙하지 않아서 구현하는데 조금 어려웠다.

주의할 점

  • 자바에선 배열을 어떻게 초기화 하는지 찾아보다가 Arryas.fill을 찾았고 아무 생각없이 적용했다가 java.lang.ArrayStoreException에러가 났다.
  • 찾아보니 2차원 배열에 값을 채우기 위해서는 for each문으로 1차? 배열을 잡아주고 fill해줘야했다.
for(boolean a[] : visited) {
	Arrays.fill(a, false);
}

풀이

public class Main {
    static char[][] grid;
    static int n;
    static int[] dy = {-1, 0, 1, 0}; // 상 좌 하 우
    static int[] dx = {0, -1, 0, 1};
    static boolean[][] visited;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        n = Integer.parseInt(br.readLine());
        grid = new char[n][n];
        visited = new boolean[n][n];

        for(int i=0; i<n; i++) { // 색그리드 생성
            String str = br.readLine();
            grid[i] = str.toCharArray();
        }

        int count = 0, rgcount = 0;

//      적록색약이 아닌 사람
        for(int i=0; i<n; i++) {
            for(int j=0; j<n; j++) {
                if(!visited[i][j]) {
                    dfs(i, j, grid[i][j]);
                    count++;
                }
            }
        }

        for(boolean a[] : visited) Arrays.fill(a, false);

        for(int i=0; i<n; i++) { // 색약 그리드 생성
            for(int j=0; j<n; j++) {
                if(grid[i][j] == 'G') grid[i][j] = 'R';
            }
        }

//      적록색약인 사람
        for(int i=0; i<n; i++) {
            for(int j=0; j<n; j++) {
                if(!visited[i][j]) {
                    dfs(i, j, grid[i][j]);
                    rgcount++;
                }
            }
        }
        System.out.println(count + " " + rgcount);
    }

    static void dfs(int y, int x, char color) {
        visited[y][x] = true;

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

            if(valCheck(nextY, nextX) == false) { // 탐색불가능하면...
                continue;
            }

            char nextColor = grid[nextY][nextX];
            if(nextColor == color) {
                visited[nextY][nextX] = true;
                dfs(nextY, nextX, nextColor);
            }
        }
    }

    static boolean valCheck(int y, int x) {
        // 탐색 했던 곳이거나 범위 밖이면 false 탐색가능하면 true;
        if(y >=0 && y < n && x >=0 && x < n && !visited[y][x]) return true;
        return false;
    }
}

 

'알고리즘' 카테고리의 다른 글

백준2583_영역구하기 (java)  (0) 2021.11.15
백준1182_부분수열의 합 (java)  (0) 2021.11.14
백준2075_N번째 큰 수 (java)  (0) 2021.11.09
백준1158_요세푸스 문제 (java)  (0) 2021.11.08
백준1764_듣보잡 (java)  (0) 2021.11.08