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
			
		
	
               
           
					
					
					
					
					
					
				