문제
https://www.acmicpc.net/problem/10026
10026번: 적록색약
적록색약은 빨간색과 초록색의 차이를 거의 느끼지 못한다. 따라서, 적록색약인 사람이 보는 그림은 아닌 사람이 보는 그림과는 좀 다를 수 있다. 크기가 N×N인 그리드의 각 칸에 R(빨강), G(초록)
www.acmicpc.net
문제 요약
크기가 N × N인 그리드의 각 칸에 R(빨강), G(초록), B(파랑) 중 하나를 색칠한 그림을 입력 받는다.
적록색약(빨간색과 초록색을 구분하지 못하는 사람)이 아닌 일반인이 봤을 때,
그림이 몇 개의 구역으로 이루어져 있는지와
적록색약(빨간색과 초록색을 구분하지 못하는 사람)인 사람이 봤을 때,
그림이 몇 개의 구역으로 이루어져 있는지를 출력한다.
같은 색상이 상하좌우로 인접해 있는 경우에 두 글자는 같은 구역에 속한다.
코드
import sys
input = __import__('sys').stdin.readline
from collections import deque # 큐
def flood_fill():
check[i][j] = val
q.append((i, j))
# 방문한 인덱스에 몇번째 구역을 방문했음을 체크하고 큐에 넣는다.
while q:
x, y = q.popleft()
for d in range(4):
nx, ny = x + dx[d], y + dy[d]
if 0 <= nx < n and 0 <= ny < n and not check[nx][ny] and color == arr[nx][ny]:
# 네 방향의 인덱스가 그리드의 범위를 벗어나지 않고
# 방문하지 않았으며
# 현재 구역의 색과 같은 색이라면
check[nx][ny] = val
# 방문했음을 표시하고
q.append((nx, ny))
# 큐에 인덱스를 넣는다.
q = deque()
# BFS를 진행할 때 사용할 큐
dx, dy = [0, 0, 1, -1], [-1, 1, 0, 0]
# 상하좌우를 탐색 할때 사용할 방향 인덱스
n = int(input())
# 그리드의 크기를 나타낼 정수
arr1 = [list(input().rstrip()) for _ in range(n)]
# 적록색약이 아닌 사람이 보는 그리드
arr2 = [tmp[:] for tmp in arr1]
# 적록색약인 사람이 보는 그리드로 사용할 2차원 배열
# 2차원 배열을 깊은 복사할 때 주의!!
# 내부 id값이 같으므로 copy함수를 사용해도 얉은 복사가 된다! (인덱싱 이용)
res = ''
# 결과를 출력할 문자열
for i in range(n):
for j in range(n):
if arr2[i][j] == 'G':
arr2[i][j] = 'R'
# 초록색을 빨간색과 같게 변경
check = [[0] * n for _ in range(n)]
# 그리드를 방문했는지 체크하는 2차원 배열
val = 1
# 인덱스를 방문했을 때 몇번째 구역인지 나타내는 변수
arr = arr1
# 배열이 두 개이므로 먼저 적록색약이 아닌 사람이 보는 그리드를 가리킨다.
for i in range(n):
for j in range(n):
if not check[i][j]:
color = arr[i][j]
# 현재 방문한 색을 나타내는 color 변수
flood_fill()
val += 1
# 방문하지 않은 인덱스가 있다면 BFS를 진행하여 인접한 칸을 val로 채운다.
res += str(val - 1) + ' '
# 결과값에 구역이 몇 개인지 추가
check = [[0] * n for _ in range(n)]
val = 1
# 적록색약의 그리드도 체크해야하므로 리셋
arr = arr2
# 적록색약의 그리드를 가리킨다. (포인터 변경)
for i in range(n):
for j in range(n):
if not check[i][j]:
color = arr[i][j]
flood_fill()
val += 1
# 다시 방문하지 않은 인덱스가 있으면 BFS를 진행해 인접한 칸을 val로 채운다.
res += str(val - 1)
print(res)
코드 설명
1. 그리드를 입력 받고, 2차원 배열 깊은 복사를 통해 적록색약이 보는 그리드를 생성한다.
2. 먼저, 입력 받은 그리드의 인덱스를 하나씩 체크하여 전에 방문하지 않은 인덱스가 있으면 flood_fill 함수를 이용하여 BFS방식으로 인접한 네 방향의 인덱스들도 확인한다.
+ 만족하는 인덱스가 있으면 큐에 넣고 다시 그 인덱스와 인접한 네 방향의 인덱스들을 확인한다.
3. 위 과정이 끝나면 적록색약이 보는 그리드에도 같은 방식으로 몇 개의 구역이 존재하는지 찾는다.
4. 결과 값을 출력한다.
'Algorithm Problems > 그래프' 카테고리의 다른 글
[백준/Python] 2468번: 안전 영역 (2) | 2023.08.29 |
---|---|
[백준/Python] 1260번: DFS와 BFS (2) | 2023.08.28 |
[백준/python] 13023번: ABCDE (0) | 2023.08.27 |
[백준/python] 2644번: 촌수계산 (0) | 2023.08.25 |
[백준/python] 1012번: 유기농 배추 (2) | 2023.08.06 |