Skip to content

Commit dd88d9c

Browse files
committed
[BOJ] 14502 연구소 (G4)
1 parent 4f62a8d commit dd88d9c

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

심수연/9주차/260226.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# https://www.acmicpc.net/problem/14502
2+
3+
from collections import deque
4+
import sys
5+
import copy
6+
input = sys.stdin.readline
7+
8+
N, M = map(int, input().split())
9+
graph = [list(map(int, input().split())) for _ in range(N)]
10+
# 0: 빈 칸, 1: 벽, 2: 바이러스
11+
12+
# 상하좌우
13+
dx = [-1, 1, 0, 0]
14+
dy = [0, 0, -1, 1]
15+
16+
empty_spaces = [] # 벽을 세울 수 있는 위치 (빈 칸인 곳)
17+
for i in range(N):
18+
for j in range(M):
19+
if graph[i][j] == 0:
20+
empty_spaces.append((i, j))
21+
22+
def bfs():
23+
queue = deque()
24+
copy_graph = copy.deepcopy(graph) # 복사
25+
26+
# 바이러스 초기 위치를 queue에 넣기
27+
for i in range(N):
28+
for j in range(M):
29+
if copy_graph[i][j] == 2:
30+
queue.append((i, j))
31+
32+
# bfs로 바이러스 퍼뜨리기
33+
while queue:
34+
x, y = queue.popleft()
35+
for i in range(4):
36+
nx = x + dx[i]
37+
ny = y + dy[i]
38+
39+
if 0 <= nx < N and 0 <= ny < M and copy_graph[nx][ny] == 0:
40+
copy_graph[nx][ny] = 2 # 바이러스 감염시키기
41+
queue.append((nx, ny))
42+
43+
# 바이러스 모두 퍼진 후 0인 부분(안전 영역) 세기
44+
count = 0
45+
for i in range(N):
46+
for j in range(M):
47+
if copy_graph[i][j] == 0:
48+
count += 1
49+
return count
50+
51+
def make_wall(count, start): # 빈 칸 중에서 3개를 골라 벽을 세우는 모든 경우의 수
52+
# 벽 3개가 세워지면 바이러스 퍼트리기
53+
global result
54+
55+
if count == 3: # 벽을 세운 후 안전 영역이 확정되었을 때
56+
result = max(result, bfs()) # 안전 영역 개수 세기 위해 bfs 사용
57+
return # 종료
58+
59+
for idx in range(start, len(empty_spaces)): # 중복 제거 위해 start 넣는것! ex) ABC = BCA
60+
i, j = empty_spaces[idx]
61+
graph[i][j] = 1 # 벽 세우고
62+
make_wall(count + 1, idx + 1) # 재귀: 두 번째 벽 세우기 -> start가 idx + 1이 됨
63+
graph[i][j] = 0 # 다시 벽 허물기 (백트래킹: 일단 해보고, 아니면 되돌아가는 탐색 방법) 3개의 벽을 세울 수 있는 모든 경우의 수를 다 보기 위해서
64+
65+
# empty_spaces = [A, B, C, D] 라고 했을 때
66+
# ABC -> C 허물고 D 선택 -> ABD -> B 허물고 C 선택 -> ACD -> A 허물고 B 선택 -> BCD
67+
# 이렇게 1 2 3 3 2 1 로 재귀 돌면서 백트래킹
68+
69+
result = 0 # 최대 안전 영역 크기
70+
make_wall(0, 0) # count = 0, start = 0으로 초기화하고 벽 세우기
71+
72+
print(result)

0 commit comments

Comments
 (0)