BOJ-10026 적록색약
https://www.acmicpc.net/problem/10026
문제 소개
R(빨강), G(초록), B(파랑)으로 이루어진 그림의 정보가 주어진다. 그리고 같은 색상이 상하좌우로 인접해 있는 경우 같은 구역이라고 정의하였다.
그림을 적록색약인 사람과 적록색약이 아닌 사람이 봤을 때 몇 개의 구역으로 나뉘어지는지 출력한다.
적록색약인 사람을 빨강과 초록의 차이를 거의 느끼지 못하며, 문제에서는 같은 색상으로 인식한다고 가정하였다.
문제 풀이
인접한 같은 색상을 BFS로 탐색하도록 하였다.
함수 bfs
는 탐색을 시작하는 좌표인 x
와 y
말고도 시작 좌표의 색상인 c
와 적록색상의 여부를 나타내는 bool형 변수인 weakness
를 매개변수로 갖는다.
bfs
는 weakness
와 c
를 토대로 인접한 색상 중 어떤 색상을 같은 구역으로 간주할 지를 변수 target
에 저장한다.
만약 적록색약인 동시에 색상이 빨강 또는 초록이라면 target
의 값은 ('R', 'G')
이며, 그 외의 경우는 c
만을 가진다.
target
의 지정 후에는 인접한 색상에 대해 bfs
를 진행하게 된다.
적록색약이 아닌 사람이 인식한 구역 수와 적록색약인 사람이 인식한 구역의 수는 각각 cnt0
, cnt1
로 나타내었다.
두 변수는 각각 0으로 초기화된 이후, weakness
로 구분되는 각각의 bfs
수행을 통해 증가한다.
마지막으로 누적된 cnt0
과 cnt1
를 출력한다.
코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
from sys import stdin
from collections import deque
input = lambda: stdin.readline().rstrip()
# 좌, 상, 우, 하 순서
d = [(0, -1), (-1, 0), (0, 1), (1, 0)]
# bfs 수행
def bfs(x, y, c, weakness: bool):
queue = deque([(x, y)])
visited[x][y] = True
# target 색상 설정
if weakness and c in ('R', 'G'):
target = ('R', 'G')
else:
target = tuple(c)
while queue:
t = queue.popleft()
for i in range(4):
nx, ny = t[0] + d[i][0], t[1] + d[i][1]
# 좌표가 유효한 범위에 속하면서 아직 방문하지 않았고 target에 포함된 경우
if 0 <= nx < n and 0 <= ny < n and not visited[nx][ny] and arr[nx][ny] in target:
queue.append((nx, ny))
visited[nx][ny] = True
n = int(input())
arr = [list(input()) for _ in range(n)]
visited = [[False] * n for _ in range(n)]
cnt0, cnt1 = 0, 0
# 적록색약이 아닌 경우
for i in range(n):
for j in range(n):
if not visited[i][j]:
bfs(i, j, arr[i][j], False)
cnt0 += 1
# visited 다시 초기화
visited = [[False] * n for _ in range(n)]
# 적록색약인 경우
for i in range(n):
for j in range(n):
if not visited[i][j]:
bfs(i, j, arr[i][j], True)
cnt1 += 1
print(cnt0, cnt1)
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.