문제
https://www.acmicpc.net/problem/15683
15683번: 감시
스타트링크의 사무실은 1×1크기의 정사각형으로 나누어져 있는 N×M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는 5가지 종류가 있다. 각 CCTV가 감
www.acmicpc.net
내 풀이
문제를 딱 봤을 때 모든 경우의 수를 구해야 하기 때문에 dfs를 사용해야 할 것 같았다. 그래서 먼저 CCTV의 번호와 위치를 cctv 리스트에 저장하였다.
CCTV는 번호에 따라서 감시하는 방향과 방향의 수가 다르다. 그래서 각 CCTV가 감시할 수 있는 모든 방향을 딕셔너리에 저장하였다.
그래고 dfs를 사용하여 모든 경우의 수를 구해주었다.
여기서 중요한 것은 tmp이다.
재귀를 돌리기 전에 tmp에 현재 space의 상태를 저장한다. 그리고 watch 함수에서 tmp의 상태를 바꿔준다. 감시를 할 수 있다면 그곳을 7로 바꿔준다.
dfs 함수에서 리턴을 하고 나면, tmp는 원상복귀 시킨다.
import sys
import copy
input = sys.stdin.readline
N, M = map(int, input().strip().split())
space = [list(map(int, input().strip().split())) for _ in range(N)]
cctv = []
for i in range(N):
for j in range(M):
if 0 < space[i][j] < 6:
cctv.append((space[i][j], i, j))
dx, dy = [0, 1, 0, -1], [1, 0, -1, 0] # 동 남 서 북
dir = {
1: [[0], [1], [2], [3]],
2: [[0, 2], [1, 3]],
3: [[3, 0], [0, 1], [1, 2], [2, 3]],
4: [[0, 1, 2], [1, 2, 3], [2, 3, 0], [3, 0, 1]],
5: [[0, 1, 2, 3]]
}
def watch(x, y, direction, tmp):
for d in direction:
nx, ny = x, y
while True:
nx += dx[d]
ny += dy[d]
if nx < 0 or nx >= N or ny < 0 or ny >= M or tmp[nx][ny] == 6: break
elif tmp[nx][ny] == 0: tmp[nx][ny] = 7
ans = 1e9
def dfs(idx, space):
global ans
tmp = copy.deepcopy(space)
if idx == len(cctv):
cnt = 0
for t in tmp:
cnt += t.count(0)
ans = min(ans, cnt)
return
num, x, y = cctv[idx]
for d in dir[num]:
watch(x, y, d, tmp)
dfs(idx+1, tmp)
tmp = copy.deepcopy(space)
dfs(0, space)
print(ans)
총평
삼성 문제 너란 문제... 아직 나에게 왜 이렇게 어렵니...
'알고리즘 > 삼성 기출' 카테고리의 다른 글
미세먼지 안녕! [백준 17144번] (0) | 2022.10.06 |
---|---|
드래곤 커브 [백준 15685번] (0) | 2022.10.06 |
인구 이동 [백준 16234번] (0) | 2022.10.01 |
치킨 배달 [백준 15686번] (0) | 2022.09.29 |
퇴사 [백준 14501번] (0) | 2022.09.22 |