킹의 개발일지
연구소 (백준 14502번) 본문
https://www.acmicpc.net/problem/14502
14502번: 연구소
인체에 치명적인 바이러스를 연구하던 연구소에서 바이러스가 유출되었다. 다행히 바이러스는 아직 퍼지지 않았고, 바이러스의 확산을 막기 위해서 연구소에 벽을 세우려고 한다. 연구소는 크
www.acmicpc.net
문제를 풀 때 벽을 어떤 규칙으로 세워야 최대 크기의 안전 영역을 구할 지 매우 고민했던 문제이다. 한참을 고민해도 마땅한 규칙이 생각나지 않아서 '이거 그냥 일일히 벽 세워보고 안전영역 세어봐야 하는거 아냐?' 라고 생각했었는데... 그게 정답이었다...
이 문제에서 주어지는 맵의 크기도 8x8이고, 벽을 세울 수 있는 모든 조합의 수는 64C3 이기에, 이는 100,000 보다도 작은수이다. 시간제한이 2초인걸 감안했을 때 충분히 제한 시간안에 해결 할 수 있다. 따라서 벽을 개수가 3개가 되는 모든 조합을 찾아서 그 안에서 탐색 알고리즘으로 계산하면 된다!
키포인트는 벽을 3개 다 세우고 바이러스를 퍼트려 그 때 안전영역을 계산한후, 제일 먼저 세웠던 벽을 지우고 다른 위치에 벽을 다시 세우는 것이 중요하다.
아래 메서드가 그 역할을 한다.
def wall(cnt):
if cnt == 3:
spread_virus()
return
for i in range(n):
for j in range(m):
if matrix[i][j] == 0:
matrix[i][j] = 1
wall(cnt+1)
matrix[i][j] = 0
전체 코드는 다음과 같다.
import sys
from collections import deque
import copy
n, m = map(int, sys.stdin.readline().split())
matrix = [list(map(int, sys.stdin.readline().split())) for _ in range(n)]
res = []
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]
# 너비 우선 탐색으로 바이러스를 퍼트린다.
# 바이러스를 퍼트린 후, 몇개인지 센다.
def spread_virus():
q = deque()
temp_map = copy.deepcopy(matrix)
cnt = 0
for i in range(n):
for j in range(m):
if temp_map[i][j] == 2:
q.append((i, j))
while q:
cx, cy = q.popleft()
for dir in range(4):
nx = dx[dir] + cx
ny = dy[dir] + cy
if 0 <= nx < n and 0 <= ny < m:
if temp_map[nx][ny] == 0:
temp_map[nx][ny] = 2
q.append((nx, ny))
for i in range(n):
for j in range(m):
if temp_map[i][j] == 0:
cnt += 1
res.append(cnt)
# 벽을 세우는 메서드
# 벽을 3개를 세웠다면 바이러스를 퍼트리고 안전영역을 센다.
# 결과를 리스트에 넣고 제일 먼저 세웠던 벽을 지우고 다시 벽을 세운다.
def wall(cnt):
if cnt == 3:
spread_virus()
return
for i in range(n):
for j in range(m):
if matrix[i][j] == 0:
matrix[i][j] = 1
wall(cnt+1)
matrix[i][j] = 0
wall(0)
print(max(res))'문제풀이' 카테고리의 다른 글
| 퇴사 (백준 14051번) (0) | 2022.12.08 |
|---|---|
| 섬의 개수(백준 4963번) (0) | 2022.12.06 |
| 치킨 배달 (백준 15686번) (0) | 2022.12.01 |
| 게임 개발(이코테 실전문제) (0) | 2022.11.30 |
| 무지의 먹방 라이브(2019 KAKAO BLIND RECRUITMENT) (0) | 2022.11.30 |