[C++] 적록색약 (10026번)

적록색약   

문제

적록색약은 빨간색과 초록색의 차이를 거의 느끼지 못한다. 따라서, 적록색약인 사람이 보는 그림은 아닌 사람이 보는 그림과는 좀 다를 수 있다.

크기가 N×N인 그리드의 각 칸에 R(빨강), G(초록), B(파랑) 중 하나를 색칠한 그림이 있다. 그림은 몇 개의 구역으로 나뉘어져 있는데, 구역은 같은 색으로 이루어져 있다. 또, 같은 색상이 상하좌우로 인접해 있는 경우에 두 글자는 같은 구역에 속한다. (색상의 차이를 거의 느끼지 못하는 경우도 같은 색상이라 한다)

예를 들어, 그림이 아래와 같은 경우에

RRRBB
GGBBB
BBBRR
BBRRR
RRRRR

적록색약이 아닌 사람이 봤을 때 구역의 수는 총 4개이다. (빨강 2, 파랑 1, 초록 1) 하지만, 적록색약인 사람은 구역을 3개 볼 수 있다. (빨강-초록 2, 파랑 1)

그림이 입력으로 주어졌을 때, 적록색약인 사람이 봤을 때와 아닌 사람이 봤을 때 구역의 수를 구하는 프로그램을 작성하시오.

입력

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

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

출력

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

 


문제풀이

 

요즘 완전탐색(DFS, BFS) 문제를 많이 푸는 것 같다.

이번 문제역시 정석에서 약간 변형된 문제다.

방문 확인 배열을 두 개로 만들어도 되고, 처음 정상일 때 한번 돌리고, 배열의 값을 G B를 G 또는 B로 전부 통일시키고 한번 돌리는 것과 같은 방식으로 해도 된다.

 

#include <iostream>
#include <string>

using namespace std;

int n;
char arr[100][100];
int visited1[100][100], visited2[100][100];

void Dfs(int r, int c, int state) {
    int rr[] = {0, 0, 1, -1};
    int cc[] = {1, -1, 0, 0};
    if(state == 0) {
        visited1[r][c] = 1;

        for(int i=0; i<4; i++) {
            int dr = r + rr[i];
            int dc = c + cc[i];

            if(dr>=0 && dr<n && dc>=0 && dc<n && visited1[dr][dc] == 0 && arr[dr][dc] == arr[r][c]) {
                Dfs(dr, dc, state);
            }
        }
    }
    else if(state == 1) {
        visited2[r][c] = 1;

        for(int i=0; i<4; i++) {
            int dr = r + rr[i];
            int dc = c + cc[i];

            if(dr>=0 && dr<n && dc>=0 && dc<n && visited2[dr][dc] == 0 && (arr[dr][dc] == arr[r][c] || (arr[r][c] == 'G' && arr[dr][dc] == 'R') || (arr[r][c] == 'R' && arr[dr][dc] == 'G'))) {
                Dfs(dr, dc, state);
            }
        }
    }
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    cin >> n;
    for(int i=0; i<n; i++) {
        string s;
        cin >> s;
        for(int j=0; j<s.size(); j++) {
            arr[i][j] = s[j];
        }
    }

    int answer1 = 0, answer2 = 0;

    for(int i=0; i<n; i++) {
        for(int j=0; j<n; j++) {
            if(visited1[i][j] == 0) {
                Dfs(i, j, 0);
                answer1++;
            }
            if(visited2[i][j] == 0) {
                Dfs(i, j, 1);
                answer2++;
            }
        }
    }
    cout << answer1 << " " << answer2;

    return 0;
}

 

'알고리즘(Algorithm)' 카테고리의 다른 글

[C++] 경사로 (14890번)  (0) 2022.12.05
[C++] 뱀과 사다리 게임 (16928번)  (0) 2022.12.04
[C++] 테트로미노 (14500번)  (1) 2022.12.01
[C++] IOIOI (5525번)  (1) 2022.11.29
[C++] 쿼드트리 (1992번)  (1) 2022.11.27