- Today
- Total
hye-log
[백준]14502번 연구소(Python) 본문
0. 문제 링크
https://www.acmicpc.net/problem/14502
14502번: 연구소
인체에 치명적인 바이러스를 연구하던 연구소에서 바이러스가 유출되었다. 다행히 바이러스는 아직 퍼지지 않았고, 바이러스의 확산을 막기 위해서 연구소에 벽을 세우려고 한다. 연구소는 크
www.acmicpc.net
1. 문제 소개
1) 구하고자 하는 것 : 안전 영역의 최대 크기 구하기
2) 주어진 것
- N X M 직사각형
- 빈 칸이면 0, 벽이면 1, 바이러스면 2로 주어짐
- 바이러스는 모든 빈 칸으로 퍼져나감(상하좌우)
- 3개의 벽을 세워서 바이러스 막기
3) 구현
- 그래프를 탐색하면서 빈 칸(0)이면 벽을 세움
- 벽을 3개 세운 후 바이러스 퍼뜨리기
- 바이러스 위치를 deque에 넣기
- deque를 하나씩 꺼내면서 네 방향에 퍼뜨리기
- 바이러스가 퍼지면 새로운 위치를 deque에 넣기
- 빈 칸(0)의 개수를 센 다음 기존 값과 비교해서 최대값 찾기
2. 입출력
# input
7 7
2 0 0 0 1 1 0
0 0 1 0 1 2 0
0 1 1 0 1 0 0
0 1 0 0 0 0 0
0 0 0 0 0 1 1
0 1 0 0 0 0 0
0 1 0 0 0 0 0
# output
27
3. 코드
from collections import deque
import copy
# input
n, m = map(int, input().split())
graph = [list(map(int, input().split())) for _ in range(n)]
result = 0
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
def bfs():
queue = deque() # 바이러스 위치를 저장할 deque 생성
tmp = copy.deepcopy(graph) # 깊은 복사
# 바이러스 위치 찾기
for i in range(n):
for j in range(m):
if tmp[i][j] == 2: # 바이러스가 있으면
queue.append((i, j)) # 큐에 추가
# 바이러스가 모두 퍼질 때까지 반복
while queue:
x, y = queue.popleft() # 큐에서 하나씩 꺼내기
for i in range(4): # 네 방향 확인
nx = x + dx[i]
ny = y + dy[i]
if (0 <= nx < n) and (0 <= ny < m): # 범위 안에 있으면
if tmp[nx][ny] == 0: # 빈 칸이면
tmp[nx][ny] = 2 # 바이러스가 퍼짐
queue.append((nx, ny)) # 해당 위치 큐에 추가
global result
count = 0
for i in range(n):
count += tmp[i].count(0)
result = max(result, count)
def make_wall(count):
if count == 3: # 벽을 3개 세웠으면
bfs() # 탐색
return
for i in range(n):
for j in range(m):
if graph[i][j] == 0: # 아무것도 없으면
graph[i][j] = 1 # 벽 1개 세우기
make_wall(count + 1) # 벽 1개 더 세우기
graph[i][j] = 0 # 원상복귀
make_wall(0)
print(result)
실행 결과
4. 회고
- 벽을 세우는 부분에서 3번을 세우기 때문에 count 변수를 이용해서 재귀 함수로 구현
- 3개의 벽을 세웠으면 bfs()를 통해 바이러스의 개수를 구하고 max 값을 구함
- 바이러스의 위치를 deque(데크)를 이용하여 넣어놓고 popleft 방식으로 꺼내옴
deque는 양방향 큐로 앞, 뒤 양방향에서 element를 추가/제거할 수 있으며, O(1) 시간 복잡도가 걸림
# deque
from collections import deque
# initialize
deq = deque()
# add element to the start
deq.appendleft(10)
# add element to the end
deq.append(0)
# pop element from the start
deq.popleft()
# pop element from the end
deq.pop()
- result는 global로 선언하여 함수 밖에서도 사용할 수 있게 정의함
- 안전 구역은 리스트에서 0인 개수를 count
5. Github
https://github.com/iihye/Algorithm/blob/main/Baekjoon/14502_laboratory.py
GitHub - iihye/Algorithm
Contribute to iihye/Algorithm development by creating an account on GitHub.
github.com
'CodingTest > Baekjoon' 카테고리의 다른 글
[백준]17413번 단어 뒤집기2(JAVA) (0) | 2023.07.29 |
---|---|
[백준]1592번 영식이와 친구들(JAVA) (0) | 2023.07.29 |
[백준]2798번 블랙잭(JAVA) (0) | 2023.07.29 |
[백준]2567번 색종이 - 2(JAVA) (0) | 2023.07.29 |
[백준]14503번 로봇 청소기(Python) (0) | 2022.10.13 |