Skip to content

Commit 73a1fc7

Browse files
committed
[BOJ] 17142 연구소 3 (G3)
1 parent c86294c commit 73a1fc7

1 file changed

Lines changed: 87 additions & 0 deletions

File tree

최어진/8주차/260219.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# 백준 17142번: 연구소 3 (3회차)
2+
3+
from collections import deque
4+
from itertools import combinations
5+
import sys
6+
7+
input = sys.stdin.readline
8+
9+
# N <= 50
10+
# M <= 10
11+
N, M = map(int, input().rstrip().split())
12+
maps = [list(map(int, input().rstrip().split())) for _ in range(N)]
13+
14+
EMPTY = 0
15+
WALL = 1
16+
VIRUS = 2
17+
NOT_VISITED = -1
18+
19+
total_viruses = []
20+
for r in range(N):
21+
for c in range(N):
22+
if maps[r][c] == VIRUS: total_viruses.append((r, c))
23+
24+
# 바이러스 조합
25+
# 10개 중 M개 선택 -> 10CM <= 10C5 = 252 < 10^3
26+
# 각 조합마다 바이러스 퍼지는 시뮬레이션
27+
# 모든 칸에 대한 BFS -> O(N^2) = 2500 < 10^4
28+
# 결론: 10^3 * 10^4 < 10^8
29+
30+
moves = [
31+
[0, 1],
32+
[0, -1],
33+
[1, 0],
34+
[-1, 0],
35+
]
36+
37+
def is_in_board(r, c):
38+
return 0 <= r < N and 0 <= c < N
39+
40+
def print_visited(visited):
41+
print('#-------#')
42+
for r in range(N):
43+
for c in range(N):
44+
if maps[r][c] == WALL: print('-', end=' ')
45+
elif visited[r][c] == NOT_VISITED:
46+
if maps[r][c] == VIRUS: print('*', end=' ')
47+
else: print('-', end=' ')
48+
else: print(visited[r][c], end=' ')
49+
print()
50+
print('#-------#')
51+
print()
52+
53+
def bfs(viruses):
54+
q = deque()
55+
visited = [[-1 for _ in range(N)] for _ in range(N)]
56+
moved_max = 0
57+
58+
for vr, vc in viruses:
59+
q.append((vr, vc, 0))
60+
visited[vr][vc] = 0
61+
62+
while q:
63+
r, c, moved = q.popleft()
64+
if maps[r][c] == EMPTY:
65+
moved_max = max(moved_max, moved)
66+
67+
for dr, dc in moves:
68+
if is_in_board(r + dr, c + dc):
69+
if maps[r + dr][c + dc] != WALL and visited[r + dr][c + dc] == NOT_VISITED:
70+
q.append((r + dr, c + dc, moved + 1))
71+
visited[r + dr][c + dc] = moved + 1
72+
73+
# print_visited(visited)
74+
75+
for r in range(N):
76+
for c in range(N):
77+
if maps[r][c] == EMPTY and visited[r][c] == NOT_VISITED: return -1
78+
79+
return moved_max
80+
81+
answer = int(1e9)
82+
for viruses in combinations(total_viruses, M):
83+
current_answer = bfs(viruses)
84+
if current_answer != -1:
85+
answer = min(answer, current_answer)
86+
87+
print(answer if answer != int(1e9) else -1)

0 commit comments

Comments
 (0)