Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 재귀
- 스택
- 완전탐색
- 스택자료구조
- socket.io
- 구현
- 문자열
- react
- 코딩테스트실력진단
- Express
- CSS
- 파이썬
- DFS활용
- DP
- DFS기초
- 블챌
- DFS
- django
- 백준
- 코테
- 자료구조
- 백준알고리즘
- 알고리즘
- 코딩테스트
- react-query
- JS
- BFS
- 그리디알고리즘
- 코드트리
- 그리디
Archives
- Today
- Total
꾸준하게 거북이처럼
백준 14502 문제 - 연구소 본문
이전 작성한 글에서 DFS의 활용과 백트래킹을 다루었는데, 14502 백준 문제와 연관이 있다.
14502번: 연구소
인체에 치명적인 바이러스를 연구하던 연구소에서 바이러스가 유출되었다. 다행히 바이러스는 아직 퍼지지 않았고, 바이러스의 확산을 막기 위해서 연구소에 벽을 세우려고 한다. 연구소는 크
www.acmicpc.net
문제
구하고자 하는 것은 바이러스가 퍼지고 난 후, 최대 안전 영역이다.
처음에는 벽 세 개를 어떻게 뽑지? 생각이 들었다. 조합을 생각할 수 있는데 여기서 DFS 활용을 적용할 수 있다.
일단 벽을 세 개 세웠을 때 모든 경우에서 바이러스가 퍼지고 난 후 면적을 모두 구하고 비교하는 방식으로 문제를 풀 수 있다.
최대 조합이 64개 중 3개 뽑는 조합으로, 10만 보다 작은 수이므로, 모든 경우의 수를 고려해도 제한 시간(이 문제는 2초) 안에 문제를 해결 할 수 있다.
(일반 컴퓨터에서 C언어로 기준으로 10억개이상의 연산 횟수를 넘어가면 1초 이상의 시간이 소요된다) => '이코테' 책 참조.
먼저 문제를 풀기 위해서 필요한 것은,
1. 벽을 세 개 세운다. => DFS 조합 적용
2. 벽에 3개가 되었을 때, 바이러스를 퍼뜨리는 함수 필요 => DFS 이용
3. 바이러스가 다 퍼지고 난 후, 해당 경우의 면적을 구하고 max를 이용해서 최대 안전 영역 구하기 => 0의 개수 구하면 됨
코드
n, m = map(int, input().split())
data = [] # 초기 맵
temp = [[0] * m for _ in range(n)] # 벽 설치 후 맵
for _ in range(n):
data.append(list(map(int, input().split())))
# 북 동 남 서 이동 방향 리스트
dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]
result = 0
#DFS를 이용해서 각 바이러스가 사방으로 퍼지도록 하기
def virus(x,y):
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
#상, 하 , 좌, 우 중에서 바이러스가 퍼질 수 있는 경우
if nx >= 0 and nx < n and ny >= 0 and ny < m:
if temp[nx][ny] == 0:
#해당 위치에 바이러스 배치하고 다시 재귀적으로 수행
temp[nx][ny] = 2
virus(nx, ny)
# 현재 맵에서 안전 영역 크기 구하기
def getScore():
score = 0
for i in range(n):
for j in range(m):
if temp[i][j] == 0:
score += 1
return score
# DFS를 이용해서 벽 설치 와 벽이 세 개가 되었을 때, 바이러스 함수 호출 후 안전 영역 크기 계산
def dfs(count):
global result
# 벽이 세 개 일 때
if count == 3:
for i in range(n):
for j in range(m):
temp[i][j] = data[i][j]
# 바이러스 전파
for i in range(n):
for j in range(m):
if temp[i][j] == 2:
virus(i,j)
# 안전 영역 최대 크기 계산
result = max(result, getScore())
return
# 빈 공간에 벽 설치
for i in range(n):
for j in range(m):
if data[i][j] == 0:
data[i][j] = 1
count += 1
dfs(count)
data[i][j] = 0
count -= 1
dfs(0)
print(result)
'Algorithm 문제 & 공부 > DFS' 카테고리의 다른 글
중복순열 구하기 (0) | 2022.06.20 |
---|---|
바둑이 승차 - CutEdgeTech (0) | 2022.06.20 |
합이 같은 부분집합 - DFS기초 (0) | 2022.06.20 |
부분집합구하기 - DFS 기초 (0) | 2022.06.20 |
DFS의 활용과 Backtracking(백트래킹) (0) | 2022.05.27 |
Comments