Bibbidi Bobbidi Boo

* 알고리즘 너무 약해서 기초 문제 50개 목표로 푸는 중...

* 3시간 안에 답을 내지 못하면 답지를 보고 30분 내로 정답 판정을 받고, 3일 뒤 다시 풀어보기


Greedy

6 / 50

 

탐색

8 / 50(NEW!)

 

기초 동적 프로그래밍

6 / 50


투포인터

1 / 10

 

이분탐색

0 / 10


문제

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

 

14502번: 연구소

인체에 치명적인 바이러스를 연구하던 연구소에서 바이러스가 유출되었다. 다행히 바이러스는 아직 퍼지지 않았고, 바이러스의 확산을 막기 위해서 연구소에 벽을 세우려고 한다. 연구소는 크

www.acmicpc.net

→ solved.ac 기준 골드 4


문제 해결 아이디어

"바이러스가 퍼진다"라는 구문에서 이전에 풀었던 토마토 문제와 비슷하다.

→ 비슷하게 bfs를 사용해서 그래프를 주면 바이러스가 퍼졌을 때, 안전 영역의 크기를 구할 수 있다.

→ 그럼 어떻게 안전 영역의 크기의 최댓값을 구할까? == 모든 벽을 세우는 모든 경우를 어떻게 구할까?

→ itertools의 조합을 사용한다.

1. 그래프에서 모든 빈칸의 인덱스를 저장한 리스트를 만든다.

2. 리스트에서 3개를 조합한다.

3. 2번에서 조합하여 나온 모든 경우에 대하여 BFS()를 수행해 가장 큰 값을 구한다.


구현

내 풀이

from collections import deque
import copy
import itertools
import sys

input = sys.stdin.readline
WALL_NUMBER = 3

# BFS 수행 알고리즘
def bfs():
  while queue:
    x, y = queue.popleft()

    # 인접한 원소(상, 하, 좌, 우)를 큐에 삽입
    for i in range(4):
      nx = x + dx[i]
      ny = y + dy[i]

      if nx < 0 or nx >= n or ny < 0 or ny >= m:
        continue

      # 빈칸인 경우 방문
      if graph[nx][ny] == 0:
        queue.append((nx, ny))
        graph[nx][ny] = 1

# 안전 영역의 크기 구하기
def get_safe_area(graph):
  result = 0
  for a in graph:
    result += a.count(0)
  return result

n, m = map(int, input().split())
input_map = [list(map(int, input().split())) for _ in range(n)]
dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]

empty_idxs = [] # 빈칸이 들어갈 수 있는 모든 인덱스
virus_idxs = [] # 바이러스가 있는 모든 인덱스
for i in range(n):
  for j in range(m):
    if input_map[i][j] == 0:
      empty_idxs.append((i, j))
    if input_map[i][j] == 2:
      virus_idxs.append((i, j))

# 빈칸이 들어간 인덱스에서 3개를 뽑아 리스트로 저장한다.
cases = list(itertools.combinations(empty_idxs, WALL_NUMBER))

answer = 0
graph = []

# 모든 경우에 대해 안전 영역의 크기 구하기
for case in cases:
  graph = copy.deepcopy(input_map)
  queue = deque(virus_idxs)
  for i, j in case:
    graph[i][j] = 1
  bfs()
  answer = max(answer, get_safe_area(graph))

print(answer)

메모

  • 걸린 시간: 30분

마치며

그동안 풀었던 골드 문제 중에 가장 적게 걸린 것 같다(감동의 눈물 좔좔좔..)

확실히 이전에 풀었던 문제를 또 접하면 쉬워보이는 경향이 있음..

역시 많이 푸는 게 답인가보다

profile

Bibbidi Bobbidi Boo

@비비디

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!