본문 바로가기
문제 해결/BOJ

[백준] 연구소 3

by 자잘 2023. 2. 26.

https://www.acmicpc.net/problem/17142

 

17142번: 연구소 3

인체에 치명적인 바이러스를 연구하던 연구소에 승원이가 침입했고, 바이러스를 유출하려고 한다. 바이러스는 활성 상태와 비활성 상태가 있다. 가장 처음에 모든 바이러스는 비활성 상태이고

www.acmicpc.net

조합 + BFS를 사용하는 문제입니다. 조합을 통해 활성화시킬 바이러스들을 선택하고 선택한 바이러스들을 시작으로 BFS를 진행해주면 됩니다. 포인트는 선택되지 못해 비활성화되어 있는 바이러스들을 만나는 경우인데 이 경우에는 큐에는 넣어주지만 모든 빈칸을 바이러스로 만들기 위해 필요한 시간으로 체크되면 안됩니다.

 

import sys
from itertools import combinations
from collections import deque

# sys.stdin = open("input.txt", "r")
input = sys.stdin.readline

n, m = tuple(map(int, input().split()))

board = [
    list(map(int, input().split()))
    for _ in range(n)
]

labor = []

for i in range(n):
    for j in range(n):
        if board[i][j] == 2:
            labor.append((i, j))

ans = sys.maxsize

dys = [0, 1, 0, -1]
dxs = [1, 0, -1, 0]

def inRange(y, x):
    return 0 <= y < n and 0 <= x < n

def virus(activated):
    global n

    temp = [
        [0] * n
        for _ in range(n)
    ]

    # 복사
    for i in range(n):
        for j in range(n):
            temp[i][j] = board[i][j]
    # 활성화되어 있는 바이러스 표시
    for (y, x) in activated:
        temp[y][x] = 3

    q = deque([(x[0], x[1], 0, True) for x in activated])

    lastTime = 0
    # 바이러스 퍼뜨리기
    while q:
        y, x, t, isActivated = q.popleft()
        # 활성화가 되어 있지 않은 바이러스가 있는 경우에는 시간을 늘리면 안된다.
        if isActivated:
            lastTime = t

        for dy, dx in zip(dys, dxs):
            ny = y + dy
            nx = x + dx

            if inRange(ny, nx) and (temp[ny][nx] == 0 or temp[ny][nx] == 2):
                # 다음이 비어있는 칸이면 활성화 시켜야함
                if temp[ny][nx] == 0:
                    temp[ny][nx] = 3
                    q.append((ny, nx, t + 1, True))
                # 비활성화되어 있는 바이러스를 활성화시키는 경우
                else:
                    temp[ny][nx] = 3
                    q.append((ny, nx, t + 1, False))

    # 바이러스가 다 퍼졌는지 확인
    for i in range(n):
        for j in range(n):
            if temp[i][j] == 0:
                return -1

    return lastTime

for combi in list(combinations(labor, m)):
    ret = virus(combi)

    if ret != -1:
        ans = min(ret, ans)

print(-1 if ans == sys.maxsize else ans)

'문제 해결 > BOJ' 카테고리의 다른 글

[백준] 미로 탈출하기  (0) 2023.03.01
[백준] 곡선 자르기  (0) 2023.02.27
[백준] 일감호에 다리 놓기  (0) 2023.02.25
[백준] 문자열 폭발  (0) 2023.02.24
[백준] 등수 찾기  (0) 2023.02.24