# 연구소 3
import sys
import copy
from collections import deque
input = sys.stdin.readline
MAX = sys.maxsize
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]
result = MAX
def bfs(arr):
global result
time = [[0] * N for _ in range(N)]
q = deque()
for i in range(N):
for j in range(N):
if arr[i][j] == 'a':
q.append((i, j))
time[i][j] = 1
while q:
x, y = q.popleft()
for k in range(4):
nx = x + dx[k]
ny = y + dy[k]
if 0 <= nx < N and 0 <= ny < N:
if time[nx][ny] == 0:
if arr[nx][ny] == 0 or arr[nx][ny] == 2:
time[nx][ny] = time[x][y] + 1
q.append((nx, ny))
else:
time[nx][ny] = -1
find_min_time(arr, time)
def find_min_time(arr, time):
global result
temp = -1
for i in range(N):
for j in range(N):
if time[i][j] == 0:
if arr[i][j] == 0:
return
elif time[i][j] != -1 and arr[i][j] != 2 and arr[i][j] != 'a':
temp = max(temp, time[i][j])
if result > temp - 1:
result = min(result, temp-1)
def active_virus(arr, count, temp):
if count == virus_num:
bfs(arr)
return
for start in range(temp+1, len(virus), 1):
x, y = virus[start]
arr[x][y] = 'a'
active_virus(arr, count+1, start)
arr[x][y] = 2
N, virus_num = map(int, input().split())
arr = []
virus = []
zerocount = 0
for i in range(N):
arr.append(list(map(int, input().split())))
for j in range(N):
if arr[i][j] == 2:
virus.append((i, j))
if arr[i][j] == 0:
zerocount += 1
temp = copy.deepcopy(arr)
active_virus(temp, 0, -1)
if zerocount == 0:
print(0)
else:
if result == MAX:
print(-1)
else:
print(result)
BFS, 백트랙킹
1. 백트랙킹으로 바이러스를 해당개수(virus_num)만큼 고르기(active_virus)
- bfs를 실행하여 q가 빌 때까지 time리스트에 바이러스가 퍼지는데 걸린 시간 초기화
- result와 time리스트 내부에서 가장 큰값(바이러스가 있는 위치 제외), 둘 중 작은 값을 result로 초기화(find_min_time)
2. 1번을 모든 경우의 수 만큼 반복
3. result 출력 (초기 리스트에 0이 없으면, 0출력)
의식의 흐름대로 막 풀었기에 코드가 매우 지저분하다...
백트랙킹 말고 콤비네이션을 이용하면 더 쉽게 할 수 있다.
'Algorithm > BOJ' 카테고리의 다른 글
[백준] 1647번 - 도시 분할 계획 (파이썬) (0) | 2022.01.21 |
---|---|
[백준] 12581번 - 숨바꼭질 2 (파이썬) (0) | 2022.01.21 |
[백준] 4485번 - 녹색 옷 입은 애가 젤다지? (파이썬) (0) | 2022.01.20 |
[백준] 1325번 - 효율적인 해킹 (파이썬) (1) | 2022.01.20 |
[백준] 2178번 - 미로 탐색 (파이썬) (0) | 2022.01.20 |