import sys
import random
floor_max = int(sys.stdin.readline().strip())
room_max = floor_max
floor_dic = {}
for i in range(1, floor_max + 1):
floor_input = sys.stdin.readline().strip()
for j in range(1, room_max + 1):
if floor_input[j - 1] == "1":
floor_dic[str(i) + " " + str(j)] = []
for floor_room in floor_dic.keys():
floor, room = map(int, floor_room.split())
# 오른쪽 방과 관련한 키를 만듭니다.
right_room = str(floor) + " " + str(room + 1)
# 옆방이 존재 한다면( 0 이 아니라면 ), 접근 가능한 방으로 현재 방의 값으로 추가 한다.
if right_room in floor_dic.keys():
floor_dic[floor_room].append(right_room)
# 왼쪽 방과 관련한 키를 만듭니다.
left_room = str(floor) + " " + str(room - 1)
# 옆방이 존재 한다면, 접근 가능한 방으로 현재 방의 값으로 추가 한다.
if left_room in floor_dic.keys():
floor_dic[floor_room].append(left_room)
# 위쪽 층의 방과 관련한 키를 만듭니다.
up_room = str(floor - 1) + " " + str(room)
# 아래 층 방이 존재 한다면, 접근 가능한 방으로 현재 방의 값으로 추가 한다.
if up_room in floor_dic.keys():
floor_dic[floor_room].append(up_room)
# 아래쪽 층의 방과 관련한 키를 만듭니다.
down_room = str(floor + 1) + " " + str(room)
# 아래 층 방이 존재 한다면, 접근 가능한 방으로 현재 방의 값으로 추가 한다.
if down_room in floor_dic.keys():
floor_dic[floor_room].append(down_room)
count_list = []
while len(floor_dic.keys()) != 0:
count = 0
# 무작위 키값을 가지고 온다. 또한 해당키로 bfs, 큐와 집합을 초기화 한다.
random_floor_room = random.choice(list(floor_dic.keys()))
bfs_queue = [random_floor_room]
bfs_set = {random_floor_room}
while len(bfs_queue) != 0:
floor_room = bfs_queue.pop(0)
for contact_room in floor_dic[floor_room]:
# 현재 방에 연결된 방 중에 접근한적 없는 방이라면
if contact_room not in bfs_set:
# 이미 접근한 방으로서 기억함
bfs_set.add(contact_room)
# 접근한 방의 주변 방을 확인하기 위해서 저장
bfs_queue.append(contact_room)
count += 1
floor_dic.pop(floor_room)
count_list.append(count)
count_list.sort()
print(len(count_list))
for i in count_list:
print(i)
대각선상으로는 연결되어 있지 않다는 가정하에 연결된 방끼리 를 단지라고 하며 각 단지에 있는 방의 개수를 오름차순으로 출력하는 문제이다.
먼저 각 방이 연결되어 있음을 확인하는 알고리즘은 2178 BFS 문제에서 이미 작성한 적 있던 코드를 사용했다.
먼저 각 방에 몇개의 방이 있는지를 확인하는 방법은 BFS 알고리즘을 사용하기로 하였다. 그렇기에 2178번 문제에서 사용했던 코드를 사용하기로 했다.
즉 특정 구역의 노드의 접근해 그 단지의 모든 방에 접근하여 방의 개수를 측정한다. 그렇다면 다음 단지를 찾는 방법은 무엇이 있는가?
랜덤한 키를 가지고 온다. 랜덤한 키를 기준으로 bfs_queue
와 bfs_set
을 초기화 한다. 그리고 기존에 작성한 bfs알고리즘을 사용해 해당 방(키)와 연결된 모든 방을 조사한다. 랜덤함 키를 받아오는 코드는 아래와 같으면 다음 페이지를 참고합니다.
random_floor_room = random.choice(list(floor_dic.keys()))
연결된 모든 방을 set
과 queue
에 추가 했다면, 현재 방(키)를 floor_dic에서 삭제 한다. 해당 키를 삭제하는 이유는 무작위 키를 받아올때 이미 연산한 단지의 방을 가져올 수 있기 때문이다.
이렇게 각 단지에 접근해 방의 개수를 연산하고 연산한 방의 개수를 리스트에 저장한다.