Notice
Recent Posts
Recent Comments
Link
할껀하고놀자
[SW역량테스트준비] 연구소 3 본문
728x90
연구소 3
연구소에 바이러스를 퍼뜨리는데 걸리는 최소시간을 구하는 문제이다.
바이러스를 놓을 수 있는 모든 경우의 수를 만든 후, 각 케이스에 대해 bfs로 바이러스를 퍼뜨려서 최소값을 구하면 된다.
-
연구소의 사이즈는 n*n이고, 바이러스의 갯수는 m개이다.
-
바이러스를 놓을 수 있는 칸의 좌표들을 리스트화하여 리스트 v에 저장하자.
-
빈칸(0)의 갯수를 모두 세고, 이를 k라고 하자. 이 값은 바이러스를 퍼트려야하는 총 개수가 된다.
-
조합을 이용해 m개의 바이러스를 후보칸에 둔다. 이때 리스트 v를 활용하여, 바이러스를 놓은 칸의 좌표를 큐에 넣는다.
-
bfs를 통해 바이러스를 퍼트린다. 감염시킬 때마다, 감염시킨 칸의 개수를 세고, 감염시간을 계속 업데이트 해준다.
-
감염은 (0)만 가능하지만, (2) 가 있는 곳으로도 감염이 가능하다.
-
bfs가 종료된 후, 감염시킨 칸의 갯수와 k의 갯수가 동일한지 확인한다.
-
만약 비교한 값이 같고, 걸린 시간이 최소라면, 정답으로 업데이트 한다.
-
모든 경우의 수에 대하여 bfs를 돌려본다.
code
from collections import deque
from sys import stdin
import sys
sys.stdin = open('input.txt')
n,m = map(int,input().split())
a = [list(map(int,input().split())) for _ in range(n)]
q,v,k = deque(),[],0
select = [False]*10
def init():
global k
for i in range(n):
for j in range(n):
if a[i][j]==2:
v.append((i,j))
if a[i][j]==0:
k+=1
def bfs(dist):
global ans
infect, times = 0,0
while q:
x,y = q.popleft()
for dx,dy in (-1,0),(0,-1),(1,0),(0,1):
nx,ny = x+dx,y+dy
if nx<0 or nx>=n or ny<0 or ny>=n:
continue
# 벽이 아니고, 아직 퍼지지 않은 곳이라면
if a[nx][ny]!=1 and dist[nx][ny] ==-1:
dist[nx][ny] = dist[x][y] + 1
q.append((nx,ny))
# 그 중에서도 0이라
if a[nx][ny] == 0:
infect += 1
times = dist[nx][ny]
# 다 퍼졌으면 갱신해주고 아니면 -1이 출력된다.
if infect == k:
ans = min(ans,times)
def solve(idx,cnt,d):
if cnt == m:
dist = [[-1]*n for _ in range(n)]
for i in range(d):
if select[i]:
x,y = v[i]
q.append((x,y))
dist[x][y] = 0 # 활성화 바이러스 안착된 곳이다
bfs(dist)
return
for i in range(idx,d):
if not select[i]:
select[i] = True
solve(i+1,cnt+1,d)
select[i] = False
ans = 10**9
init()
solve(0,0,len(v))
print(ans if ans!=10**9 else -1)
'[IT]' 카테고리의 다른 글
[SW역량테스트준비] 캐슬 디펜스 (0) | 2019.10.19 |
---|---|
[SW역량테스트준비] 치킨 배달 (0) | 2019.10.17 |
[SW역량테스트준비] 아기상어 (0) | 2019.10.13 |
[C++]define와 typedef의 차이점 (0) | 2018.02.15 |
[Win32] visual studio 2017에 c++ winform 도구상자 띄우기 (7) | 2018.02.11 |
Comments