Point πŸ’‘


μƒν•˜μ’Œμš° xμ’Œν‘œ, yμ’Œν‘œ 리슀트 κ·ΈλŒ€λ‘œ 해놓고, cctv λ°©ν–₯을 κ·Έ μ’Œν‘œ 리슀트의 index둜 μ„€μ •ν•΄μ„œ κ΅¬ν•œλ‹€.

dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]

# 각 cctvλ³„λ‘œ κ°μ‹œν•  수 μžˆλŠ” λ°©ν–₯
direction = [
    [], # cctvκ°€ μ—†λŠ” κ²½μš°λ„ μžˆμ„ 수 있음
    [[0], [1], [2], [3]],
    [[0, 2], [1, 3]],
    [[0, 1], [1, 2], [2, 3], [0, 3]],
    [[0, 1, 2], [0, 1, 3], [1, 2, 3], [0, 2, 3]],
    [[0, 1, 2, 3]],
]

My Solution


import sys
from copy import deepcopy

input = sys.stdin.readline
n, m = map(int, input().split())
cctv = []
office = []

# νŠœν”Œλ‘œ xμ’Œν‘œ, yμ’Œν‘œλ‘œ ꡬ성 -> dic으둜 λ°”κΏˆ, ꡳ이 xμ’Œν‘œ/yμ’Œν‘œλ‘œ λ‚˜λˆ μ„œ λ„£μ§€μ•ŠμŒ
# 각 cctvλ³„λ‘œ κ°μ‹œν•  수 μžˆλŠ” λ°©ν–₯
direction = [
    [], # cctvκ°€ μ—†λŠ” κ²½μš°λ„ μžˆμ„ 수 있음
    [[0], [1], [2], [3]],
    [[0, 2], [1, 3]],
    [[0, 1], [1, 2], [2, 3], [0, 3]],
    [[0, 1, 2], [0, 1, 3], [1, 2, 3], [0, 2, 3]],
    [[0, 1, 2, 3]],
]

# μœ„ - 였 - μ•„λž˜ - μ™Ό
# direction λ¦¬μŠ€νŠΈκ°€ 이 μ’Œν‘œλ¦¬μŠ€νŠΈμ˜ 인덱슀λ₯Ό λ‚˜νƒ€λ‚΄λ―€λ‘œ cctv λ°©ν–₯ 쑰건에 λ§žμΆ”μ–΄ μœ„ - 였 - μ•„λž˜ - μ™Ό μˆœμ„œλ‘œ μ΄ˆκΈ°ν™”
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]

for i in range(n):
    data = list(map(int, input().split()))
    office.append(data)
    for j in range(m):
        if data[j] in [1, 2, 3, 4, 5]:
            # cctv의 μ’…λ₯˜μ™€ μœ„μΉ˜λ₯Ό cctv 리슀트λ₯Ό μ—…λ°μ΄νŠΈ
            cctv.append([data[j], i, j])

def fill(x, y, d, office_copy) :
    for i in d:
        nx = x
        ny = y
        while True:
            # μƒν•˜μ’Œμš° xμ’Œν‘œ, yμ’Œν‘œ 리슀트 κ·ΈλŒ€λ‘œ 해놓고, cctv λ°©ν–₯을 μ’Œν‘œ 리슀트의 index둜 μ„€μ •ν•΄μ„œ ꡬ함
            nx += dx[i]
            ny += dy[i]

            # λ²”μœ„μ„ λ²—μ–΄λ‚¬μœΌλ©΄
            if nx < 0 or ny < 0 or nx >= n or ny >= m:
                break

            # 벽을 λ§Œλ‚¬λ‹€λ©΄
            if office_copy[nx][ny] == 6:
                break

            # 0이라면, '#'λŒ€μ‹  '-1'둜 λ³€κ²½μ‹œν‚€κΈ°
            elif office_copy[nx][ny] == 0:
                office_copy[nx][ny] = -1

def dfs(depth, office):
    global answer

    if depth == len(cctv):
        count = 0

        # μ‚¬κ°μ§€λŒ€ κ΅¬ν•˜λŠ” ν•¨μˆ˜
        for i in range(n):
            count += office[i].count(0)

        # 각 μΌ€μ΄μŠ€λ§ˆλ‹€ μ‚¬κ°μ§€λŒ€ 개수 κ°€μž₯ μž‘μ€ κ°’μœΌλ‘œ μ—…λ°μ΄νŠΈ
        answer = min(answer, count)
        return

    # μ›λž˜ office에 영ν–₯을 λ―ΈμΉ˜μ§€ μ•Šκ²Œ ν•˜κΈ° μœ„ν•΄μ„œ μ‚¬μš©
    office_tmp = deepcopy(office)
    cctv_num, x, y = cctv[depth]

    for d in direction[cctv_num]:
        fill(x, y, d, office_tmp)
        dfs(depth + 1, office_tmp)
        # dfs 탐색 μ™„λ£Œ 후에 κ·Έ 이전 μƒνƒœλ‘œ 돌리기 μœ„ν•΄ μ‚¬μš© -> κ·Έλž˜μ•Ό dfs 탐색 쀑에 μˆ˜ν–‰λœ 변경사항 μ·¨μ†Œκ°€λŠ₯
        office_tmp = deepcopy(office)

answer = int(1e9)
dfs(0, office)
print(answer)