clap0107
[백준] 14502번 연구소 - 파이썬 본문
반응형
https://www.acmicpc.net/problem/14502
14502번: 연구소
인체에 치명적인 바이러스를 연구하던 연구소에서 바이러스가 유출되었다. 다행히 바이러스는 아직 퍼지지 않았고, 바이러스의 확산을 막기 위해서 연구소에 벽을 세우려고 한다. 연구소는 크
www.acmicpc.net
풀이:
bfs를 사용해야 한다는 것은 눈치챌 수 있었지만 벽을 놓는 조건을 어떻게 구현해야 할지 생각하느라 어려웠다.
처음에는 규칙이 존재하는 줄 알고 조건을 하나하나 적으려고 했지만 경우의 수가 너무 많음을 깨달았다.
그래서 벽을 쌓고 bfs로 탐색하는 과정을 계속 반복하여 모든 경우의 수를 체크하는 방법을 생각했지만 뭔가 이렇게 되면 시간 초과가 날 것 같았다.
그리고 모든 경우의 수를 고려하여 벽을 쌓는 코드를 어떻게 구현해야 할지 몰랐다.
구글링으로 재귀를 사용하면 된다는 걸 배웠다.
하지만 생각한 데로 python3로 하니 시간이 초과하여 더욱 빠른 pypy3을 사용할 수밖에 없었다.
결국 다시 구글링을 하니 파이썬에는 combination(조합)을 지원하는 모듈이 있다는 걸 배웠다.
재귀를 사용하게 되면 permutaion(순열)의 방식이어서 시간 초과가 나는 것 같다.
그래서 combination을 사용하니 python3로도 통과가 되었다.
알고리즘 공부는 갈길이 멀다...
재귀를 사용한 코드:
import sys
import copy
from collections import deque
input = sys.stdin.readline
def bfs():
queue = deque()
trial = copy.deepcopy(grid)
for i in range(len(virus)):
queue.append(virus[i])
while queue:
y, x = queue.popleft()
for i in range(4):
ny = dy[i] + y
nx = dx[i] + x
if ny <= -1 or ny >= n or nx <= -1 or nx >= m:
continue
if trial[ny][nx] == 0:
trial[ny][nx] = 2
queue.append([ny, nx])
global safe
safe_current = 0
for i in range(n):
safe_current += trial[i].count(0)
safe = max(safe, safe_current)
def walls(count):
if count == 3:
bfs()
return
for y in range(n):
for x in range(m):
if grid[y][x] == 0:
grid[y][x] = 1
walls(count + 1)
grid[y][x] = 0
n, m = map(int, input().split())
grid = []
virus = []
safe = 0
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
for _ in range(n):
grid.append(list(map(int, input().split())))
for y in range(n):
for x in range(m):
if grid[y][x] == 2:
virus.append([y, x])
walls(0)
print(safe)
combination을 사용한 코드:
import sys
import copy
from collections import deque
from itertools import combinations
input = sys.stdin.readline
def bfs():
for i in combinations(blank, 3):
queue = deque()
trial = copy.deepcopy(grid)
for y, x in i:
trial[y][x] = 1
for i in range(len(virus)):
queue.append(virus[i])
while queue:
y, x = queue.popleft()
for i in range(4):
ny = dy[i] + y
nx = dx[i] + x
if ny <= -1 or ny >= n or nx <= -1 or nx >= m:
continue
if trial[ny][nx] == 0:
trial[ny][nx] = 2
queue.append([ny, nx])
global safe
safe_current = 0
for i in range(n):
safe_current += trial[i].count(0)
safe = max(safe, safe_current)
n, m = map(int, input().split())
grid = []
virus = []
blank = []
safe = 0
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
for _ in range(n):
grid.append(list(map(int, input().split())))
for y in range(n):
for x in range(m):
if grid[y][x] == 2:
virus.append([y, x])
if grid[y][x] == 0:
blank.append([y, x])
bfs()
print(safe)
반응형
'코딩테스트 > DFS/BFS' 카테고리의 다른 글
[백준] 2644번 촌수계산 - 파이썬 (0) | 2023.02.19 |
---|---|
[백준] 1987번 알파벳 - 파이썬 (2) | 2023.02.19 |
[백준] 2206번 벽 부수고 이동하기 - 파이썬 (0) | 2023.02.15 |
[백준] 4963번 섬의 개수 - 파이썬 (0) | 2023.02.13 |
[백준] 7576번 토마토 - 파이썬 (0) | 2023.02.12 |
Comments