[백준 BFS, 백트래킹] 연구소(python)
문제
https://www.acmicpc.net/problem/14502
나의 코드 (답안 참조)
"""
1. 아이디어
n, m의 범위가 작은걸 보고 완전탐색을 이용해서 풀어야 하나 생각 했어야 했다.
모든 경우에 벽은 다 일일이 세어보고 바이러스를 유포시킨 다음 안전지대의 개수를 세야 한다.
2. 시간복잡도
O(NM^4)인가?
일단 BFS 부분은 알려져 있듯이 O(NM)이고 벽을 3개 세우는 부분은
모든 부분에 대해 탐색해야 하므로 O(NM^3)이라고 생각한다. 그리고 완전탐색을
돌리는 와중에 BFS가 호출되므로 결국 O(NM^4)가 되고 N과 M은 각각 8이 최대니깐
(8 * 8)^4 = 2^24 = 16,777,216 충분한데?
"""
from collections import deque
from sys import stdin
import copy
input = stdin.readline
n, m = map(int, input().split())
map = [ list(map(int, input().split())) for _ in range(n) ]
answer = 0
dx, dy = [0, 0, -1, 1], [-1, 1, 0, 0]
def bfs():
global answer
q = deque()
map2 = copy.deepcopy(map) # 2차원 배열을 복사하는 부분
""" 바이러스가 있는 지점에서 시작한다.
동시에 유포해야 하니깐 이렇게 미리 바이러스 지점을 큐에 집어넣는다."""
for i in range(n):
for j in range(m):
if map2[i][j] == 2:
q.append((i, j))
while q:
px, py = q.popleft()
for k in range(4):
mx = px + dx[k]
my = py + dy[k]
if 0 <= mx < n and 0 <= my < m:
if map2[mx][my] == 0:
map2[mx][my] = 2
q.append((mx, my))
global answer
cnt = 0
for i in range(n):
cnt += map2[i].count(0)
answer = max(answer, cnt)
def wall(cnt): # 백트래킹 부분. 벽이 3개 다 세워지면 bfs를 탐색한다.
if cnt == 3:
bfs()
return
for i in range(n):
for j in range(m):
if map[i][j] == 0:
map[i][j] = 1
wall(cnt+1)
map[i][j] = 0
wall(0)
print(answer)
느낀점
- 백트래킹을 이용해서 모든 경우의 벽을 세우는 부분
- copy를 import해서 bfs 탐색할때 마다 임시 2차원 배열을 생성하는 부분
"""
1. 아이디어
n, m의 범위가 작은걸 보고 완전탐색을 이용해서 풀어야 하나 생각 했어야 했다.
모든 경우에 벽은 다 일일이 세어보고 바이러스를 유포시킨 다음 안전지대의 개수를 세야 한다.
2. 시간복잡도
O(NM^4)인가?
일단 BFS 부분은 알려져 있듯이 O(NM)이고 벽을 3개 세우는 부분은
모든 부분에 대해 탐색해야 하므로 O(NM^3)이라고 생각한다. 그리고 완전탐색을
돌리는 와중에 BFS가 호출되므로 결국 O(NM^4)가 되고 N과 M은 각각 8이 최대니깐
(8 * 8)^4 = 2^24 = 16,777,216 충분한데?
"""
from collections import deque
from sys import stdin
import copy
input = stdin.readline
n, m = map(int, input().split())
map = [ list(map(int, input().split())) for _ in range(n) ]
answer = 0
dx, dy = [0, 0, -1, 1], [-1, 1, 0, 0]
def bfs():
global answer
q = deque()
map2 = copy.deepcopy(map) # 2차원 배열을 복사하는 부분
""" 바이러스가 있는 지점에서 시작한다.
동시에 유포해야 하니깐 이렇게 미리 바이러스 지점을 큐에 집어넣는다."""
for i in range(n):
for j in range(m):
if map2[i][j] == 2:
q.append((i, j))
while q:
px, py = q.popleft()
for k in range(4):
mx = px + dx[k]
my = py + dy[k]
if 0 <= mx < n and 0 <= my < m:
if map2[mx][my] == 0:
map2[mx][my] = 2
q.append((mx, my))
global answer
cnt = 0
for i in range(n):
cnt += map2[i].count(0)
answer = max(answer, cnt)
def wall(cnt): # 백트래킹 부분. 벽이 3개 다 세워지면 bfs를 탐색한다.
if cnt == 3:
bfs()
return
for i in range(n):
for j in range(m):
if map[i][j] == 0:
map[i][j] = 1
wall(cnt+1)
map[i][j] = 0
wall(0)
print(answer)
- 백트래킹을 이용해서 모든 경우의 벽을 세우는 부분
- copy를 import해서 bfs 탐색할때 마다 임시 2차원 배열을 생성하는 부분
위의 2가지 부분을 확실히 알고가야할 문제이다
Author And Source
이 문제에 관하여([백준 BFS, 백트래킹] 연구소(python)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@tyjk8997/백준-백트래킹BFS-연구소python저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)