1) 좌표를 다루는 방법
def fill(x, y, arr, dset):
for d in dset:
nx, ny = x, y
while True:
# dx, dy를 사용해 탐색
nx += dx[d]
ny += dy[d]
if 0 <= nx < n and 0 <= ny < m:
if arr[nx][ny] == 6:
break
elif arr[nx][ny] == 0:
arr[nx][ny] = '#'
else:
break
2) 상태를 복원하는 방법 2가지
temp = copy.deepcopy(arr)
out = sys.maxsize
for dset in direction[ctype]:
fill(x, y, temp, dset)
out = min(out, solve(depth+1, temp))
temp = copy.deepcopy(arr)
#
arr = [1,2,3]
arr2 = []
arr2.extend(arr)
arr2[0] = 3
print(arr2, arr) # [3, 2, 3] [1, 2, 3]
#
arr = [1,2,3]
arr3 = arr
arr3[0] = 2
print(arr3, arr) # [2, 2, 3] [2, 2, 3]
1) 좌표문제이므로 dx, dy를 정의한다
2) cctv 타입마다 회전 방향에 따라 감시하는 방향을 정의한다
3) cctv 위치를 저장해둔다
4) DFS 에서 cctv를 한개씩 꺼내서 회전방향에 따라 상태를 바꾸고, DFS 돌리고, 복원하고 동작을 반복한다
1) cctv 감시 여부를 나타내는 state array를 따로 만들었었는데
그럴필요없이 처음 주어진 지도에 다른 기호로 표시했으면 됐다
2) 상태 복원을 위해 state 를 True, False 로 구현했는데,
copy.deepcopy를 사용해 상태를 복원하는게 훨씬 안전하다
3) 상태를 글로벌 변수로 사용해 관리하지 말고, copy 해서 fill함수에 넣어주고 상태를 변경했어야 했다
4) 파이썬은 list 함수 인자를 레퍼런스로 받으므로 별도의 리턴 없이 함수 내부에서 변경한게 함수 외부에서도 반영된다
def func(arr, a):
arr[0] = 2
a = 1
arr = [1,2,3]
a = 2
func(arr, a)
print(arr, a) # [2, 2, 3] 2
4) 풀이가 지나치게 복잡하다면 의심해보자 fill 함수처럼 간단하게 할 수 있어야한다
import sys, copy
# 모든 방향 에 대해 채우는 방법에 대해 정의할 필요 없이,
# 방향이 주어지면 맵이 끝날때까지 채운다
def fill(x, y, arr, dset):
for d in dset:
nx, ny = x, y
while True:
nx += dx[d]
ny += dy[d]
if 0 <= nx < n and 0 <= ny < m:
if arr[nx][ny] == 6:
break
elif arr[nx][ny] == 0:
arr[nx][ny] = '#'
else:
break
def solve(depth, arr):
if depth == len(cctv_pos):
result = 0
for i in range(n):
for j in range(m):
if arr[i][j] == 0:
result += 1
return result
x, y , ctype = cctv_pos[depth]
# dfs 탐색 후에 탐색 전 상태로 복원하기 위해 deepcopy 사용
temp = copy.deepcopy(arr)
out = sys.maxsize
for dset in direction[ctype]:
fill(x, y, temp, dset)
out = min(out, solve(depth+1, temp))
temp = copy.deepcopy(arr)
return out
sys.stdin = open('15683.txt')
n, m = list(map(int, input().split()))
data = []
for _ in range(n):
data.append(list(map(int, input().split())))
# 아래, 위, 오른쪽, 왼쪽
dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]
direction = [[],[[0],[1],[2],[3]],
[[2,3], [1,0], [3,2], [0,1]],
[[2,1], [1,3], [3,0], [0,2]],
[[0,1,2], [1,2,3], [0,2,3], [0,1,3]],
[[0,1,2,3]]]
cctv_pos = []
for i in range(n):
for j in range(m):
if data[i][j] in [1,2,3,4,5]:
cctv_pos.append([i,j, data[i][j]]) # (i, j, cctv type)
out = solve(0, data)
print(out)