알고리즘/문제 풀이

10026번: 적록색약

Themion 2021. 12. 29. 16:44

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

 

10026번: 적록색약

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

www.acmicpc.net

입력받은 2차원 배열의 각 성분을 노드, 인접한 노드 사이의 관계를 에지로 보면, 이 문제는 그래프 탐색을 통해 같은 값을 가진 인접한 노드 집합의 수를 세는 문제이다. 이 때 일반적으로 그래프를 탐색할 경우 visit 배열을 사용해 해당 좌표를 방문했는지 여부를 판단하지만, 주어진 문제에선 그래프를 두 번 탐색해야 하고 그룹을 어느정도 유지해야 하므로, 탐색한 노드의 값을 바꾸는 방법으로 탐색해야 한다.

첫 탐색 때는 값이 'R' 혹은 'G'인 노드의 값을 임의의 값 a로, 값이 'B'인 노드의 값은 임의의 값 b로 탐색하며 이외의 값은 바꾸지 않는다. 그래프 탐색을 한 번 마친 후, 두 번째 탐색에선 값이 'a' 혹은 'b'인 노드의 값을 다른 임의의 값으로 바꾸며 다시 한 번 탐색한다. 이 두 번의 탐색에서 얻은 그룸의 수를 각각 출력하면 된다.

#include <cstdio>

#define MAX_N 100

// 그림을 저장할 공간
char image[MAX_N][MAX_N + 1];
// N: 그림의 한 변의 길이, add: 좌표의 상하좌우 좌표를 계산할 때 사용할 값
int N, add[4][2] = { {0, -1}, {0, 1}, {-1, 0}, {1, 0} };

// 좌표 (x, y)가 포함되며 값이 from인 구역을 순회하며 값을 to로 바꾼다
bool dfs(int y, int x, char from, char to) {
    // 좌표 (x, y)와 인접한 좌표를 계산할 때 사용할 변수
    int y_, x_;

    // 현재 좌표의 값을 to로 바꾼 뒤
    image[y][x] = to;
    // 현재 좌표와 인접한 좌표에 대해
    for (auto a : add) {
        // 좌표값을 계산한 뒤
        y_ = y + a[0]; x_ = x + a[1];
        // 좌표가 valid하지 않다면 continue
        if (y_ < 0 || y_ >= N || x_ < 0 || x_ >= N) continue;
        // 해당 좌표의 값이 from이라면 dfs를 통해 방문
        else if (image[y_][x_] == from) dfs(y_, x_, from, to);
    }

    // 편의를 위해 true를 반환
    return true;
}

int main() {
    // RGB: 색약이 아닌 사람이 봤을 때 구역의 수, ab: 색약인 사람이 봤을 때 구역의 수 
    int RGB = 0, ab = 0;

    // 문제의 조건을 입력받은 뒤
    scanf("%d", &N);
    for (int i = 0; i < N; i++) scanf("%s", image[i]);

    // 구역을 계산하며 RGB 이미지를 적녹 색약에 맞게 a, b로 바꿔준다 
    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)
        if (image[i][j] == 'R' || image[i][j] == 'G' || image[i][j] == 'B')
            RGB += dfs(i, j, image[i][j], (image[i][j] == 'B') ? 'b' : 'a');

    // 구역을 계산하며 확인한 좌표를 0으로 초기화
    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)
        if (image[i][j] == 'a' || image[i][j] == 'b')
            ab += dfs(i, j, image[i][j], 0);

    printf("%d %d\n", RGB, ab);

    return 0;
}

'알고리즘 > 문제 풀이' 카테고리의 다른 글

10166번: 관중석  (0) 2021.12.29
10039번: 평균 점수  (0) 2021.12.29
9935번: 문자열 폭발  (0) 2021.12.29
9663번: N-Queen  (0) 2021.12.29
9655번: 돌 게임  (0) 2021.12.29