상세 컨텐츠

본문 제목

파이썬으로 풀어보는 백준 17142번: 연구소 3 (삼성 A형 기출 문제)

Python/문제풀이 (삼성 A형 대비)

by 코딩하는 낙타 2020. 2. 11. 14:35

본문

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

 

17142번: 연구소 3

인체에 치명적인 바이러스를 연구하던 연구소에 승원이가 침입했고, 바이러스를 유출하려고 한다. 바이러스는 활성 상태와 비활성 상태가 있다. 가장 처음에 모든 바이러스는 비활성 상태이고, 활성 상태인 바이러스는 상하좌우로 인접한 모든 빈 칸으로 동시에 복제되며, 1초가 걸린다. 승원이는 연구소의 바이러스 M개를 활성 상태로 변경하려고 한다. 연구소는 크기가 N×N인 정사각형으로 나타낼 수 있으며, 정사각형은 1×1 크기의 정사각형으로 나누어져 있다. 연구소는

www.acmicpc.net

 

내 풀이:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
def BFS(lst):
    global ans
    q = []
    for idx in lst:
        q.append(virus[idx])
    visited = [[False] * N for _ in range(N)]
    new = [arr[i][:] for i in range(N)]
    for y, x in q:
        visited[y][x] = True
    result = 0
    while q:
        TF = True
        for c in range(len(q)):
            y, x = q.pop(0)
 
            for dir in range(4):
                ny = y + dy[dir]
                nx = x + dx[dir]
 
                if 0 <= ny <= N-1 and 0 <= nx <= N-1 and not visited[ny][nx]:
                    if new[ny][nx] == 0:
                        new[ny][nx] = 2
                        visited[ny][nx] = True
                        q.append((ny, nx))
                        TF = False
 
                    elif new[ny][nx] == 2:
                        visited[ny][nx] = True
                        q.append((ny, nx))
 
        if TF:
            break
        result += 1
 
 
    for i in range(N):
        for j in range(N):
            if new[i][j] == 0:
                return
 
    if ans > result:
        ans = result
 
 
def order(idx, lst):
    global cnt
    if len(lst) == M:
        BFS(lst)
        return
 
 
    for i in range(lst[-1]+1len(virus)):
        if i not in lst:
            lst.append(i)
            order(idx + 1, lst)
            lst.pop()
 
N, M = map(int,input().split())
arr = [list(map(int,input().split())) for _ in range(N)]
ans = 3000
dy = [-1010]
dx = [010-1]
 
virus = []
cnt = 0
for i in range(N):
    for j in range(N):
        if arr[i][j] == 2:
            virus.append((i, j))
            cnt += 1
 
for i in range(len(virus)):
    order(1, [i])
 
if ans == 3000:
    print(-1)
else:
    print(ans)
 

Python3, 1000ms

전형적인 BFS 탐색 문제인 것 같다. 다만 주의해야 할 점은 이미 0은 모두 제거했는데 뒤늦게 활성화된 바이러스가 큐에 들어갈 수 있기 때문에 0이 하나도 발견되지 않은 경우에 while문을 나갈 수 있도록 장치를 해주었다.

관련글 더보기

댓글 영역