코로나 시국에 맞는 BFS DFS를 모두 사용해서 해결할 수 있는 좋은 문제라고 생각한다.
연구소는 크기가 N×M인 직사각형으로 나타낼 수 있으며, 직사각형은 1×1 크기의 정사각형으로 나누어져 있다. 연구소는 빈 칸, 벽으로 이루어져 있으며, 벽은 칸 하나를 가득 차지한다.
일부 칸은 바이러스가 존재하며, 이 바이러스는 상하좌우로 인접한 빈 칸으로 모두 퍼져나갈 수 있다. 새로 세울 수 있는 벽의 개수는 3개이며, 꼭 3개를 세워야 한다.
0은 빈 칸, 1은 벽, 2는 바이러스가 있는 곳이다.
2 1 0 0 1 1 2 1 0 1 0 1 2 2 0 1 1 0 1 2 2 0 1 0 0 0 1 2 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0
벽을 3개 세운 뒤, 바이러스가 퍼질 수 없는 곳을 안전 영역이라고 한다. 위의 지도에서 안전 영역의 크기는 27이다.
연구소의 지도가 주어졌을 때 얻을 수 있는 안전 영역 크기의 최댓값을 구하는 프로그램을 작성하시오.
벽을 반드시 세 개 세워야 한다 : 0이 적혀 있는 칸 3개를 골라 1로 바꿔주어야 한다.. 라고 이해했다.
N, M = map(int, sys.stdin.readline().split())
lab = [list(map(int, sys.stdin.readline().split())) for _ in range(N)]
start = [(i,j) for i in range(N) for j in range(M) if lab[i][j] == 2]
blank_room = [(i,j) for i in range(N) for j in range(M) if lab[i][j] == 0]
빈 방들 중에서 3개를 뽑는다면 이는 조합으로 풀 수 있을 것이라 판단했다.
벽을 세우는 함수를 구현한다.
lab[x][y] = 1
)cnt+1
), 뽑은 위치 다음부터 시작하기 위한 변수를 저장한다(i+1
)lab[x][y] = 0
) corona(start,lab)
)def wall(cnt,s):
global answer
if cnt == 3:
res = corona(start,lab)
if res > answer:
answer = res
return
else :
for i in range(s,len(blank_room)):
x,y = blank_room[i]
lab[x][y] = 1
wall(cnt+1,i+1)
lab[x][y] = 0
바이러스를 퍼뜨리고 감염되지 않는 방의 개수를 구하는 함수를 구현한다.
연구실에 바이러스를 퍼뜨리고 개수를 세는 것 까지는 좋으나 개수를 센 이후에는 초기화 과정이 필요하다. 다른 곳에 벽을 세우는 경우에도 개수를 세고 어느 값이 더 큰지 비교해야 하기 때문이다.
이를 위해 연구소 배열을 복제( copy.deepcopy(lab)
)하는 방법을 선택했다.
바이러스를 퍼뜨리는 과정은 bfs를 통해 구현하였다.
남아있는 0을 세어 결과값으로 리턴한다.
from collections import deque
from copy import deepcopy
def corona(start,lab):
simulate = deepcopy(lab)
result = 0
queue = deque(start)
while queue:
x,y = queue.popleft()
for dx,dy in (1,0),(0,1),(-1,0),(0,-1):
nx,ny = x+dx,y+dy
if 0 <= nx < N and 0 <= ny < M and not simulate[nx][ny]:
queue.append((nx,ny))
simulate[nx][ny] = 2
for i in simulate:
for j in i :
if j == 0 :
result += 1
return result
from collections import deque
from copy import deepcopy
import sys
def corona(start,lab):
simulate = deepcopy(lab)
result = 0
queue = deque(start)
while queue:
x,y = queue.popleft()
for dx,dy in (1,0),(0,1),(-1,0),(0,-1):
nx,ny = x+dx,y+dy
if 0 <= nx < N and 0 <= ny < M and not simulate[nx][ny]:
queue.append((nx,ny))
simulate[nx][ny] = 2
for i in simulate:
for j in i :
if j == 0 :
result += 1
return result
def wall(cnt,s):
global answer
if cnt == 3:
res = corona(start,lab)
if res > answer:
answer = res
return
else :
for i in range(s,len(blank_room)):
x,y = blank_room[i]
lab[x][y] = 1
wall(cnt+1,i+1)
lab[x][y] = 0
N, M = map(int, sys.stdin.readline().split())
lab = [list(map(int, sys.stdin.readline().split())) for _ in range(N)]
start = [(i,j) for i in range(N) for j in range(M) if lab[i][j] == 2]
blank_room = [(i,j) for i in range(N) for j in range(M) if lab[i][j] == 0]
answer = 0
wall(0,0)
print(answer)