꾸르꾸르

[BOJ] 10026번 적록색약 풀이 (C++) 본문

코딩, 알고리즘, 문제풀이/BOJ 백준

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

GGUGGU- 2019. 6. 4. 19:42

2018.1.17 에 쓰여진 글입니다.


문제링크

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

 

10026번: 적록색약

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

www.acmicpc.net

 

풀이방법

일단 이문제는 바로 이전글에 포스팅한 안전구역과 비슷한 느낌의 문제이다.

재귀를 이용한 DFS로 풀면 바로 풀리는 간단한 문제.

일단 영역체크를 4가지로 나누어서 함

1. 빨간색(R) 영역

2. 초록색(G) 영역

3. 파란색(B) 영역

4. 적록색약(R, G) 영역

이 영역들의 개수를 area 배열에 저장해주는게 기본 풀이 방법.

 

이 영역들의 개수를 구할때는 함수를 2개로 만들어서

solve 함수는 정상 사람이 봤을때 해당영역을 체크하는 함수

solve_n 은 적록색약인 사람이 봤을때 영역을 체크하는 함수

이다.

이렇게해서 구하면 바로 풀리는데..

 

2019년에 다시 보니까 밑에 코드는 무려 1년 반전에 짠코드라...

코드가 좀 많이 맘에 안들지만 고치는건 역시나 다음으로 미루도록 한다..

내일의 내가 하겠지뭐...

 

소스코드

#include <iostream>
#include <cstdio>
 
using namespace std;
 
char map[100][100];
bool visited[100][100];
bool area_check;
int area[4];    //r g b rg 영역 체크 
int N;
int dx[] = { -1,0,1,0 };
int dy[] = { 0,-1,0,1 };
 
 
void solve(int cur_x, int cur_y, char color)        //r g b영역체크 함수
{
    if (!visited[cur_x][cur_y] && map[cur_x][cur_y] == color) {    //방문안했고 해당 색이 같다면
        area_check = true;    //area check true로 
        visited[cur_x][cur_y] = true;        //방문표시해주기
        for (int i = 0; i < 4; i++) {        //상하좌우 돌리기
            int new_x = cur_x + dx[i];
            int new_y = cur_y + dy[i];
            if (0 <= new_x&&new_x < N && 0 <= new_y&&new_y < N        //범위안에 있고
                && !visited[new_x][new_y]) {                        //방문안했다면
                solve(new_x, new_y, color);            //solve함수 호출
            }
        }
    }
}
 
void solve_n(int cur_x, int cur_y)        //rg 즉 적록색약 영역체크함수
{
    if (!visited[cur_x][cur_y] && (map[cur_x][cur_y] == 'R' || map[cur_x][cur_y] == 'G')) {
        area_check = true;
        visited[cur_x][cur_y] = true;
        for (int i = 0; i < 4; i++) {
            int new_x = cur_x + dx[i];
            int new_y = cur_y + dy[i];
            if (0 <= new_x&&new_x < N && 0 <= new_y&&new_y < N
                && !visited[new_x][new_y]) {
                solve_n(new_x, new_y);
            }
        }
    }
}
 
void Init_visited()
{
    for (int i = 0; i < 100; i++)
        for (int j = 0; j < 100; j++)
            visited[i][j] = false;
}
 
int main()
{
    for (int i = 0; i < 4; i++)
        area[i] = 0;
    cin >> N;
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            scanf("%1s", &map[i][j]);        //맵입력받음
 
    Init_visited();        //방문초기화
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            for (int k = 0; k < 3; k++) {
                area_check = false;
                if (k == 0)                //RED 영역 체크
                    solve(i, j, 'R');
                else if (k == 1)        //GREEN 영역 체크
                    solve(i, j, 'G');
                else
                    solve(i, j, 'B');        //BLUE 영역 체크
                if (area_check)        //area check 가 true면 
                    area[k]++;        //해당영역 갯수 증가
            }
    Init_visited();        //방문초기화
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++) {
            area_check = false;
            solve_n(i, j);        //적록색약 영역체크 
            if (area_check)
                area[3]++;
        }
    //정상영역, 적록색약 영역 출력
    cout << area[0] + area[1] + area[2] << " " << area[2] + area[3] << endl;
 
    return 0;
}
Comments