https://www.acmicpc.net/problem/2583
Solution
1) M,N paper 배열을 만들어준 뒤, 직사각형에 해당하는 부분만 1로 바꾸어준다. 색종이 문제 https://claude-u.tistory.com/299 참고.
2) BFS 너비우선 탐색을 이용해서 직사각형에 해당하지 않는 부분 부분의 크기를 탐색해준다.
3) 함수에서는 block의 크기만 필요함으로 len(block)을 return해준다.
4) 이후 0,0부터 M,N까지 이중 for문을 돌려 BFS함수를 실행해준다.
Python Code
#블록이 몇개인지 알아내기 위한 BFS 너비 우선 탐색 함수를 정의
def bfs(i, j):
global visited, paper
if paper[i][j] == 1: #직사각형 내부일 경우(1일 경우) 함수를 넘김
visited.append([i, j])
return
block = [] #함수 안에서만 쓰일 블록
queue = [[i, j]] #함수 안에서만 쓰일 큐
while queue:
[i, j] = queue.pop(0)
block.append([i, j]) #블록에 쌓아줌
visited.append([i, j]) #방문 리스트에 쌓아줌
if paper[i][j] == 0: #각각 상하좌우를 확인하는 조건문
if i < M-1 and paper[i+1][j] == 0 and [i+1, j] not in block and [i+1, j] not in queue:
queue.append([i+1, j])
if j < N-1 and paper[i][j+1] == 0 and [i, j+1] not in block and [i, j+1] not in queue:
queue.append([i, j+1])
if i > 0 and paper[i-1][j] == 0 and [i-1, j] not in block and [i-1, j] not in queue:
queue.append([i-1, j])
if j > 0 and paper[i][j-1] == 0 and [i, j-1] not in block and [i, j-1] not in queue:
queue.append([i, j-1])
return len(block) #블록의 크기만 출력하면 된다
#입력
M, N, K = map(int, input().split())
paper = [[0 for _ in range(N)] for _ in range(M)]
#입력 - 직사각형 좌표 내부를 1로 바꾸어줌
for _ in range(K):
x1, y1, x2, y2 = map(int, input().split())
for i in range(y1, y2):
for j in range(x1, x2):
paper[i][j] = 1
#함수 실행
visited = []
block_list = []
#0,0 부터 M,N까지 각각의 블록에 관하여 함수 실행문
for i in range(M):
for j in range(N):
if [i, j] not in visited:
block = bfs(i, j)
if block:
block_list.append(block)
#출력문
print(len(block_list))
for i in sorted(block_list):
print(i, end= ' ')
'Programming [Python] > 백준 알고리즘 솔루션' 카테고리의 다른 글
#265 백준 파이썬 [2193] 이친수 - 피보나치 수열 (0) | 2019.12.09 |
---|---|
#264 백준 파이썬 [10995] 별 찍기 - 20 (0) | 2019.12.09 |
#262 백준 파이썬 [1158] 조세퍼스 문제 (2) | 2019.12.08 |
#261 백준 파이썬 [2566] 최댓값 (0) | 2019.12.04 |
#260 백준 파이썬 [15663] N과 M (9) - 순열 (0) | 2019.12.04 |