코딩테스트-알고리즘/백준 BOJ

[백준 BOJ/Gold V] 10026번 : 적록색약

닉네임생각즁 2024. 2. 12. 03:29

 

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

 

10026번: 적록색약

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

www.acmicpc.net

 

이렇게 풀어도 되는걸까,,? 라는 생각으로 물음표 가득 띄운채 풀었는데 시간도 메모리도 엄청 여유롭게 통과해서 놀랐다😮😮😮

이런 방식으로 풀면 답은 나오겠다 싶긴 했지만 같은 과정을 여러번 반복하는 느낌이라서 시간이든 메모리든 초과가 나올 줄 알았다 글 작성하고나서 다른 사람들의 풀이를 찾아볼 예정,,

 

 

 

DFS 알고리즘을 이용하였고 문자별로 각각 카운트해주었다

전체 grid 배열을 돌면서

- R 만남 → checkR → 이어져있는 R 구역을 확인하고, 확인한 R은 Z로 바꿔서 다시 방문하지 않도록 함  → 이어진 R을 모두 확인한 후 돌아와서 r 값을 하나 더해줌 (R구역을 하나 확인했다는 의미)

- G 만남 → checkG → 이어져있는 G 구역을 확인하고, 확인한 G는 Z로 바꿔서 다시 방문하지 않도록 함 → 이어진 G를 모두 확인한 후 돌아와서 g 값을 하나 더해줌 (G구역을 하나 확인했다는 의미)

⭐ R과 G를 같은 문자로 바꿔준 이유는 나중에 하나의 색으로 계산하기 위함이다 ( 적록색약은 R, G 두개의 색을 같은 색으로 보기 때문에)

- B 만남 → checkB → 이어져있는 B 구역을 확인하고, 확인한 B는 C로 바꿔서 다시 방문하지 않도록 함 → 이어진 B 를 모두 확인한 후 돌아와서 b 값을 하나 더해줌 ( B구역을 하나 확인했다는 의미)

 

적록색약인 사람이 보는 것도 확인해야하기 때문에 R과 G를 묶은 Z를 확인하기 위해 전체 배열을 한번 더 돌아줌

- Z 만남 → checkRG → 이어져있는 Z 구역을 확인하고, 확인한 Z는 Y로 바꿔서 다시 방문하지 않도록 함  → 이어진 Z를 모두 확인한 후 돌아와서 rg 값을 하나 더해줌 (Z구역을 하나 확인했다는 의미)

 

모두 확인했으면 최종 답을 계산해주면 된다

- 적록색약이 아닌 사람 : result1 = r + g + b

- 적룍색약인 사람 : result2 = rg + b

 

 

 

최종 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    static int[] dx = {-1, 1, 0, 0};
    static int[] dy = {0, 0, -1, 1};
    static int N;
    static String[][] grid;
    static int r = 0;
    static int g = 0;
    static int rg = 0;
    static int b = 0;


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

        for(int i = 0; i < N; i++) {
            String[] str = br.readLine().split("");
            for(int j = 0; j < N; j++) {
                grid[i][j] = str[j];
            }
        }

        for(int i = 0; i < N; i++) {
            for(int j = 0; j < N; j++) {

                if (grid[i][j].equals("R")) {
                    checkR(i, j);
                    r++;
                }

                else if(grid[i][j].equals("G")) {
                    checkG(i, j);
                    g++;
                }

                else if(grid[i][j].equals("B")) {
                    checkB(i, j);
                    b++;
                }
            }
        }


        for(int i = 0; i < N; i++) {
            for(int j = 0; j < N; j++) {
                if(grid[i][j].equals("Z")) {
                    checkRG(i, j);
                    rg++;
                }
            }
        }


        int result1 = r + g + b;
        int result2 = rg + b;

        System.out.println(result1 + " " + result2);

    }

    static void checkR(int x, int y) {
        grid[x][y] = "Z";

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

            if(nx >= 0 && nx < N && ny >= 0 && ny < N) {
                if(grid[nx][ny].equals("R")) checkR(nx, ny);
            }
        }
    }

    static void checkG(int x, int y) {
        grid[x][y] = "Z";

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

            if(nx >= 0 && nx < N && ny >= 0 && ny < N) {
                if(grid[nx][ny].equals("G")) checkG(nx, ny);
            }
        }
    }

    static void checkB(int x, int y) {
        grid[x][y] = "C";

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

            if(nx >= 0 && nx < N && ny >= 0 && ny < N) {
                if(grid[nx][ny].equals("B")) checkB(nx, ny);
            }
        }
    }

    static void checkRG(int x, int y) {
        grid[x][y] = "Y";

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

            if(nx >= 0 && nx < N && ny >= 0 && ny < N) {
                if(grid[nx][ny].equals("Z")) checkRG(nx, ny);
            }
        }
    }

}

 

 

한문제만 더 풀면 실버2로 올라갈듯!! 골드로 빨리 가고싶다🏃‍♂️🏃‍♀️🏃‍♂️🏃‍♀️

 

 

 

 

 

 

+

2024.02.28

코테 스터디를 하면서 깨달은 내용

- 한글자씩 쓰이는 경우에는 String 배열이 아니라 char 배열이 훨씬훨씬좋다!!!!

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    static int[] dx = {-1, 1, 0, 0};
    static int[] dy = {0, 0, -1, 1};
    static int N;
    static char[][] grid;
    static int r = 0;
    static int g = 0;
    static int rg = 0;
    static int b = 0;


    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];

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

        for(int i = 0; i < N; i++) {
            for(int j = 0; j < N; j++) {

                if (grid[i][j] == 'R') {
                    checkR(i, j);
                    r++;
                }

                else if(grid[i][j] == 'G') {
                    checkG(i, j);
                    g++;
                }

                else if(grid[i][j] == 'B') {
                    checkB(i, j);
                    b++;
                }

            }
        }

        for(int i = 0; i < N; i++) {
            for(int j = 0; j < N; j++) {
                if(grid[i][j] == 'Z') {
                    checkRG(i, j);
                    rg++;
                }
            }
        }

        int result1 = r + g + b;
        int result2 = rg + b;

        System.out.println(result1 + " " + result2);

    }

    static void checkR(int x, int y) {
        grid[x][y] = 'Z';

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

            if(nx >= 0 && nx < N && ny >= 0 && ny < N) {
                if(grid[nx][ny] == 'R') checkR(nx, ny);
            }
        }
    }

    static void checkG(int x, int y) {
        grid[x][y] = 'Z';

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

            if(nx >= 0 && nx < N && ny >= 0 && ny < N) {
                if(grid[nx][ny] == 'G') checkG(nx, ny);
            }
        }
    }

    static void checkB(int x, int y) {
        grid[x][y] = 'C';

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

            if(nx >= 0 && nx < N && ny >= 0 && ny < N) {
                if(grid[nx][ny] == 'B') checkB(nx, ny);
            }
        }
    }

    static void checkRG(int x, int y) {
        grid[x][y] = 'Y';

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

            if(nx >= 0 && nx < N && ny >= 0 && ny < N) {
                if(grid[nx][ny] == 'Z') checkRG(nx, ny);
            }
        }
    }

}

 

 

String 배열로 풀었을 때:

 

 

char 배열로 풀었을 때: