python-for-coding-test
python-for-coding-test copied to clipboard
p.341 연구소 문제 풀이 중 이해가 안 가는 부분 질문입니다!
책 풀이 중에 마지막 하단의 코드 부분에서 어떻게 3개의 벽을 설치하는 모든 경우의 수를 탐색하나요?
for i in range(n):
for j in range(m):
# 빈 공간에만 벽을 설치할 수 있음
if data[i][j] == 0:
data[i][j] = 1 # 벽 설치
count += 1 # 설치한 벽 수 +1
dfs(count)
data[i][j] = 0
count -= 1 # 복구한 벽을 설치한 벽 수에서 -1 차감
그래서 제가 아래의 일일이 출력하는 코드까지 작성해서 해보았는데 결과화면에서 이상한 점을 발견했는데요? 아래와 같이 인풋 데이터가 주어졌다고 할 때, 최초의 벽은 (0, 0) , (0, 1) , (1, 1) 위치에 순차적으로 벽을 설치하고 안전영역 계산 후에 (1, 1) 위치의 벽을 허물고 난 후 (1, 2) 위치에 벽을 설치하고 ... (반복) 하잖아요? 이렇게 (0, 0), (0, 1) 벽 설치를 고정시키고 주어진 범위 안에서 설치할 수 있는 벽 위치의 마지막 값인 (1, 2)위치의 벽을 설치하고 난 후 안전영역 계산 후 (1, 2) 위치의 벽을 허문다음 갑자기 (0, 1)의 벽을 허무는데요? 이 부분이 이해가 안갑니다. 갑자기 연속으로 2번 허물게 되는 로직이 어디서 발생하는 건가요? 만약 (0, 1)의 벽을 허물려면 data[0][1] == 0의 조건을 만족해야 하는데, 현재는 (0, 1) 위치에 벽이 설치(data[0][1] = 1 이기 떄문)되었기 때문에 i=0, j=1 일 때, 벽을 허무는 조건문으로 들어갈 수 없지 않나요? 답변 아시면 꼭 부탁드립니다... 꼭 이해해보고 싶네요.. 어떤 점을 제가 오해하고 있는지 알려주시면 감사하겠습니다!
이거는 제가 의심하는 부분의 출력 결과 화면이고 그 아래는 해당 출력 결과를 출력하는 코드 입니다.

import numpy as np
n, m = map(int, input().split())
data = [] # 주어지는 맵 정보 담을 리스트
temp = [[0] * m for _ in range(n)] # 주어진 맵 정보 + 설치한 벽 3개 반영할 리스트
for _ in range(n):
data.append(list(map(int, input().split())))
# 4가지 이동 방향
dx = [0, 0, 1, -1]
dy = [1, -1, 0, 0]
result = 0 # 안전영역 계산 초기값
# 1. 바이러스 퍼지는 공간을 DFS로 탐색
def virus_dfs(x, y):
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if 0 <= nx < n and 0 <= ny < m:
# 전파시키려고 하는 곳이 빈 공간이면 전염
if temp[nx][ny] == 0:
temp[nx][ny] = 2
# 재귀적으로 DFS
virus_dfs(nx, ny)
# 2. 주어진 맵 정보와 새로운 벽 3개 설치 후 바이러스 전파시킨 후 안전영역 계산 함수
def get_score():
score = 0
for i in range(n):
for j in range(m):
if temp[i][j] == 0:
score += 1
return score
# 3. 벽 설치하는 경우의 수를 DFS로 탐색하면서 1번 경우의 수마다 바이러스 전파 및 안전영역 계산 -> 경우의 수 탐색할 때마다 안전영역 최댓값 업데이트
def dfs(count):
print('dfs가 실행되었어요!', 'count:', count)
global result
# 설치한 벽 개수가 3개 도달했을 때
if count == 3:
# 주어진 맵 정보 & 새로 설치한 벽 3개 정보를 -> temp 리스트에다가 반영 for 안전영역 계산하기 위해
for i in range(n):
for j in range(m):
temp[i][j] = data[i][j]
# 업데이트 된 맵 temp를 일일이 돌면서 바이러스일 때 전파 함수 수행
for i in range(n):
for j in range(m):
if temp[i][j] == 2:
virus_dfs(i, j)
# 바이러스 전파 모두 끝난 후 안전영역 계산 및 기존 안전영역과 업데이트
result = max(result, get_score())
return
# 3개 벽을 설치하는 경우의 수를 DFS로 탐색
# 처음에 돌 때는 (i=0, j=0)으로 고정하고 재귀함수를 다 돌은 다음, 끝에 도달하면 (i=0, i=1
for i in range(n):
for j in range(m):
# 빈 공간에만 벽을 설치할 수 있음
if data[i][j] == 0:
print('='*50)
print('새로 설치한 벽:', (i, j))
data[i][j] = 1 # 벽 설치
count += 1 # 설치한 벽 수 +1
print(np.array(data))
dfs(count) # 재귀적으로 수행하면서 위에서 벽 설치한 공간(1) 말고 다른 설치할 수 있는 공간에다가 다른 벽 설치
data[i][j] = 0 # 마지막에 설치한 벽 복구?
count -= 1 # 복구한 벽을 설치한 벽 수에서 -1 차감
print('-'*50)
print('취소한 벽:', (i, j))
print(np.array(data))
dfs(0)
print(result)