ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준 10026] 적록색약
    C 프로그래밍/BOJ 2022. 8. 27. 14:29
    728x90

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

    10026번: 적록색약

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

    www.acmicpc.net

    #include <iostream>
    #include <cstdio>
    #include <string>
    int N;
    char pic_for_diff[100 + 10][100 + 10];	// 적록색약이 아닌 사람 
    char pic_for_same[100 + 10][100 + 10];	// 적록색약인 사람
    int diff[100 + 10][100 + 10];	// 적록색약이 아닌 사람의 방문 표시
    int same[100 + 10][100 + 10];	// 적록색약인 사람의 방문 표시
    int diff_cnt; 	// 적록색약이 아닌 사람의 영역 개수
    int same_cnt;	// 적록색약인 사람의 영역 개수
    
    int dir_x[4] = { 1, -1, 0, 0 };
    int dir_y[4] = { 0, 0, -1, 1 };
    
    void input(void)
    {
    	scanf("%d", &N);
    	for (int i = 0; i < N; i++) {
    		scanf("%s", &pic_for_diff[i]);
    	}
    }
    
    
    void make_metrix(void)	// 적록색약용 행렬 한개 더 생성	// G자리에 R 대입
    {
    	for (int i = 0; i < N; i++) {
    		for (int j = 0; j < N; j++) {
    			if (pic_for_diff[i][j] == 'R') pic_for_same[i][j] = 'G';
    			else pic_for_same[i][j] = pic_for_diff[i][j];
    		}
    	}
    }
    
    void RGB(int x, int y, char c)	// 적록색약이 아닌 사람 
    {
    	diff[x][y] = 1;
    
    	for (int p = 0; p < 4; p++) {
    		int nx = x + dir_x[p];
    		int ny = y + dir_y[p];
    		if (nx < 0 || nx > N - 1 || ny < 0 || ny > N - 1 || diff[nx][ny] == 1 || pic_for_diff[nx][ny] != c)  continue;
    		else if (pic_for_diff[nx][ny] == c && !diff[nx][ny]) RGB(nx, ny, c);
    	}
    }
    
    
    void GB(int x, int y, char c)	// 적록색약인 사람 
    {
    	same[x][y] = 1;
    
    	for (int p = 0; p < 4; p++) {
    		int nx = x + dir_x[p];
    		int ny = y + dir_y[p];
    		if (nx < 0 || nx > N - 1 || ny < 0 || ny > N - 1 || same[nx][ny] == 1 || pic_for_same[nx][ny] != c)  continue;
    		else if (pic_for_same[nx][ny] == c && !same[nx][ny]) GB(nx, ny, c);
    	}
    }
    
    
    void search(void)
    {
    	for (int i = 0; i < N; i++) {
    		for (int j = 0; j < N; j++) {
    			if (pic_for_same[i][j] == 'G' && !same[i][j]) {	// same if 문으로 따로
    				GB(i, j, 'G');
    				same_cnt++;
    			}
    			if (pic_for_diff[i][j] == 'G' && !diff[i][j]) {	// diff if~else 문으로 따로 
    				RGB(i, j, 'G');
    				diff_cnt++;
    			}
    			else if (pic_for_diff[i][j] == 'B' && !diff[i][j]) {	// 파랑은 둘 다 본다.
    				RGB(i, j, 'B');
    				diff_cnt++;
    				GB(i, j, 'B');
    				same_cnt++;
    			}
    			else if (pic_for_diff[i][j] == 'R' && !diff[i][j]) {
    				RGB(i, j, 'R');
    				diff_cnt++;
    			}
    		}
    	}
    }
    
    
    int main()
    {
    	input();
    	make_metrix();
    	search();
    	printf("%d %d", diff_cnt, same_cnt);
    	return 0;
    }

    // make_metrix() 함수
    음.. 이문제는 어떻게 풀까 하다가, 그냥 적록색약용(R == G) 행렬을 더 만들어서 풀었다. 조건문으로 R일때 G일때를 하나의 함수에서 처리해주려고 하니까, 코드짜는 나도 헷갈려서... 메모리를 조금 더 쓰더라도 행렬 4개(pic_for_diff, pic_for_same, diff, same)로 돌렸다.


    // RGB(), GB() 함수
    기능은 똑같이 방문처리 및 영역 탐색을 위한 함수이다. 사실 두 함수의 기능이 100% 동일해서 (1. 방문 행렬을 same을 쓰느냐, diff를 쓰느냐 2. 참조 행렬을 pic_for_diff를 쓰느냐 pic_for_same을 쓰느냐의 차이만 존재) 하나로 합쳐볼까 하다가... 이것도 조건문 코드짜다가 헷갈려서 분리하기로..


    // search() 함수
    내가 이 문제를 두-번이나 틀린 이유가 여기에 있다. 조건문으로 각각 R / G / B를 만났을 경우를 나눠서 루프를 돌려주었다. 그런데 "적록색약이 G를 만나는 것"과 "적록색약이 아닌 사람이 G를 만나는 것"은 독립사건이므로, 4개의 조건문을 if~else if로 묶어주면 안된다. 적록색약이 G를 만나는 경우, 적록색약이 아닌 사람이 R /G/ B를 만나는 경우를 따로따로 생각해주어야 한다는 것이다.
    따라서 적록색약용 if 문 따로, 적록색약이 아닌 사람용 if~else if 구문을 따로 만들어 주었고, 색깔이 B인 경우는 둘 다 구분가능하므로, RGB(), GB() 함수를 같이 불러서 탐색하도록 구현했다.


    ++ 22.09.14 다시 품

    728x90

    'C 프로그래밍 > BOJ' 카테고리의 다른 글

    [백준 15961] 회전 초밥  (1) 2022.08.29
    [백준 15686] 치킨 배달  (0) 2022.08.28
    [백준 2583] 영역 구하기  (0) 2022.08.27
    [백준 1012] 유기농 배추  (0) 2022.08.25
    [백준 2606] 바이러스  (0) 2022.08.24

    댓글

Designed by Tistory.