-
[Python] 백준 2234 성곽알고리즘/문제풀이 2021. 10. 9. 15:41728x90
1. 문제 링크
https://www.acmicpc.net/problem/2234
2. 문제 요약
- 방의 개수 구하기
- 가장 넓은 방 구하기
- 하나의 벽 제거 시 가장 넓은 방 크기 구하기
3. 아이디어 정리
- bfs를 이용하여 탐색을 한다.
- 방문 안 한 방 중 상하좌우 탐색하여 벽을 찾는다.
- 벽이 존재하는 경우 "3. 하나의 벽 제거 시 가장 넓은 방 크기 구하기"를 구하기 위해 근처 벽 변수에 넣어준다.
- 벽이 존재하지 않는 경우 현재 방의 크기를 늘려주고 deque에 넣어준다.
- 현재 그래프에서 bfs 탐색이 끝나면 가장 넓은 방의 넓이를 갱신하고, dict로 된 room_num[방 번호] = 방 크기 저장한다.
- 근처 벽 변수로 하나의 벽을 제거하여 얻을 수 있는 가장 넓은 방의 크기 구한다.
4. 문제 풀이
4-1. 내 풀이
import sys from collections import deque from collections import defaultdict def find_imposs(num): """ 벽 찾기 """ list_ = list() if num >= 8: num -= 8 list_.append(1) if num >= 4: num -= 4 list_.append(3) if num >= 2: num -= 2 list_.append(0) if num >= 1: num -= 2 list_.append(2) return list_ # 상, 하, 좌, 우 dx = [-1, 1, 0, 0] dy = [0, 0, -1, 1] n, m = map(int, sys.stdin.readline().split()) graph = [list(map(int, sys.stdin.readline().split())) for _ in range(m)] graph_num = [[-1] * n for _ in range(m)] # 방 번호 저장 room_num = defaultdict(int) # 방마다 총 넓이 저장 near_room = set() # 주변 방 저장 count = 0 # 이 성에 있는 방의 개수 max_room = 0 # 가장 넓은 방의 넓이 for i in range(m): for j in range(n): if graph_num[i][j] == -1: # 방문하지 않은 경우 탐색 dq = deque([(i, j)]) count += 1 graph_num[i][j] = count num = 1 # 해당 방의 넓이 while dq: x, y = dq.popleft() imposs = find_imposs(graph[x][y]) # 상하좌우 중 벽 리스트 얻기 for d in range(4): nx = x + dx[d] ny = y + dy[d] if nx < 0 or ny < 0 or nx >= m or ny >= n: continue if d in imposs and graph_num[nx][ny] != -1: # 벽이고, 주변 벽에 번호가 존재하는 경우, 주변 벽리스트에 저장 if graph_num[nx][ny] != count: near_room.add((count, graph_num[nx][ny])) if d in imposs or graph_num[nx][ny] != -1: # 벽이거나 방문을 한 경우 그만 continue graph_num[nx][ny] = count dq.append((nx, ny)) num += 1 # 총 방의 수 세기 max_room = max(max_room, num) # 가장 넓은 방의 넓이 구하기 room_num[count] = num # 각 방별 크기 저장 # 하나의 벽을 제거하여 얻을 수 있는 가장 넓은 방의 크기 구하기 max_two_room = 0 for x, y in near_room: max_two_room = max(max_two_room, room_num[x] + room_num[y]) print(count) print(max_room) print(max_two_room)
5. 결론
- 섬의 수 구하기 문제와 비슷하다. 그러나 벽을 직접 처리&벽을 제거하여 가장 넓은 방 구하기 처리를 해야한다.
- bfs 응용문제
'알고리즘 > 문제풀이' 카테고리의 다른 글
[Python] 백준 2470 두 용액 (0) 2021.10.30 [Python] Programmers 더 맵게 (0) 2021.10.10 [Python] 백준 1174 줄어드는 숫자 (1) 2021.10.08 [Python] 백준 17129 윌리암슨수액빨이딱따구리가 정보섬에 올라온 이유 (0) 2021.10.08 [Python] Programmers 단어 변환 (0) 2021.10.06