[python]백준 10026 풀이

한상욱·2023년 7월 19일
post-thumbnail

적록색약

백준 10026 문제 링크

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

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

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

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

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

입력

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

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

출력

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

풀이

저는 각각 상황에 따른 BFS 함수를 각각 작성해서 문제를 해결했습니다.

일반적인 사람의 경우 모든 색상을 각각 구분해서 구역을 구분할 수 있어야합니다. 따라서 함수 내부에서 해당 좌표의 색상을 지정하고 색상과 같다면 방문처리를 하면서 구역을 카운팅한다면 일반적인 구역수는 구할 수 있습니다.

적록색약인 경우 빨강과 초록을 같은 색상으로 처리해야 합니다. 그렇기 때문에 문자를 입력받으면 적록색약인 사람이 바라보는 색상을 출력하는 함수를 작성해서 위의 BFS알고리즘을 살짝 변형시켜 적록색약인 사람이 바라보는 구역을 구할 수 있습니다.

import sys
from collections import deque
input = sys.stdin.readline

n = int(input().rstrip())


visited_normal = [[False for _ in range(n)] for _ in range(n)]
visited_special = [[False for _ in range(n)] for _ in range(n)]

dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]
picture = []

cnt_normal = 0 # 적록색약이 아닌 사람이 바라보는 그림의 구역수
cnt_special = 0 # 적록색약인 사람이 바라보는 그림의 구역수

def color(x): # 색상을 판별하는 함수
    if x == 'B':
        return 'B'
    else:
        return 'X'

def bfs(x, y): # 적록색약이 아닌 사람들의 BFS 함수
    q = deque()
    q.append((x, y))
    color = picture[x][y]
    while q:
        x, y = q.popleft()
        for i in range(4):
            nx, ny = x+dx[i], y+dy[i]
            if nx < 0 or nx >= n or ny < 0 or ny >= n:
                continue

            if not visited_normal[nx][ny] and picture[nx][ny] == color:
                visited_normal[nx][ny] = True
                q.append((nx, ny))


def bfs_special(x, y): # 적록색약인 사람들의 BFS 함수
    q = deque()
    q.append((x, y))
    c = color(picture[x][y])
    while q:
        x, y = q.popleft()
        for i in range(4):
            nx, ny = x+dx[i], y+dy[i]

            if nx < 0 or nx >= n or ny < 0 or ny >= n:
                continue

            if not visited_special[nx][ny] and color(picture[nx][ny]) == c:
                visited_special[nx][ny] = True
                q.append((nx, ny))

            
for _ in range(n):
    picture.append(list(input().rstrip()))

# 반복문을 수행해서 각각의 상황에 따른 구역을 카운팅
for i in range(n):
    for j in range(n):
        if not visited_normal[i][j]:
            cnt_normal += 1
            bfs(i, j)

        if not visited_special[i][j]:
            cnt_special += 1
            bfs_special(i, j)

print(cnt_normal, cnt_special) # 정답 출력

+

근데, 제가 풀었지만 문제를 너무 무식하게 해결했습니다 ㅋㅋㅋ 적록색약인 사람의 그림을 따로 만들고 하나의 BFS를 수행하는게 더 효율적일듯 합니다.

profile
자기주도적, 지속 성장하는 모바일앱 개발자의 기록

2개의 댓글

comment-user-thumbnail
2023년 7월 19일

소중한 정보 감사드립니다!

1개의 답글