반응형
https://www.acmicpc.net/problem/15683
15683번: 감시
스타트링크의 사무실은 1×1크기의 정사각형으로 나누어져 있는 N×M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는 5가지 종류가 있다. 각 CCTV가 감시할 수 있는 방법은 다음과 같다. 1번 CCTV는 한 쪽 방향만 감시할 수 있다. 2번과 3번은 두 방향을 감시할 수 있는데, 2번은 감시하는 방향이 서로 반대방향이어야 하고, 3번은 직각 방향이어야 한다. 4번은 세 방향, 5번은 네 방향을 감시할
www.acmicpc.net



DFS 문제.
문제 자체는 쉽게 이해할 수 있었지만, 코드로 어떻게 구현할지가 머리 아팠던 문제.
C++이나 자바로 풀었던 다른 코드에는 '왼쪽 / 위쪽' 같은 90도 단위나 '왼쪽 / 위쪽 / 오른쪽' 같은 270도 단위도 어떻게든 indexing으로 풀던데, 나는 봐도 이해가 안 돼서 그냥 풀었다. 어차피 90도 단위나 270도 단위 모두 경우의 수는 4개뿐이어서, 하드코딩 식으로 작업해도 정답에는 문제가 없었다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
from copy import deepcopy | |
import math | |
n, m = map(int, sys.stdin.readline().split()) | |
maps = [] | |
cctvs = [] | |
for y in range(n): | |
temp = list(map(int, sys.stdin.readline().split())) | |
for x in range(m): | |
if 1 <= temp[x] <= 5: | |
cctvs.append((y,x,temp[x])) | |
maps.append(deepcopy(temp)) | |
mins = math.inf | |
# dirs | |
# 0 = 왼쪽 | |
# 1 = 위 | |
# 2 = 오른쪽 | |
# 3 = 아래 | |
def check_map(maps, dirs, y, x): | |
maps = deepcopy(maps) | |
for looking in dirs: | |
if looking == 0: | |
for dx in range(x, len(maps[0])): | |
if maps[y][dx] == 6: | |
break | |
elif maps[y][dx] != 0: | |
continue | |
else: | |
maps[y][dx] = "#" | |
elif looking == 1: | |
for dy in range(y, -1, -1): | |
if maps[dy][x] == 6: | |
break | |
elif maps[dy][x] != 0: | |
continue | |
else: | |
maps[dy][x] = "#" | |
elif looking == 2: | |
for dx in range(x, -1, -1): | |
if maps[y][dx] == 6: | |
break | |
elif maps[y][dx] != 0: | |
continue | |
else: | |
maps[y][dx] = '#' | |
elif looking == 3: | |
for dy in range(y, len(maps)): | |
if maps[dy][x] == 6: | |
break | |
elif maps[dy][x] != 0: | |
continue | |
else: | |
maps[dy][x] = '#' | |
return maps | |
def detecting(maps, cctvs, idx): | |
global mins | |
if idx == len(cctvs): | |
value = 0 | |
for y in range(len(maps)): | |
value += maps[y].count(0) | |
mins = min(mins, value) | |
return | |
cctv = cctvs[idx] | |
y, x, kind = cctv | |
if kind == 1: | |
for i in range(4): | |
next_maps = check_map(maps, [i], y, x) | |
detecting(next_maps, cctvs, idx+1) | |
# 사방향 탐색값 total_amount에 넣는다 | |
# 다음 탐색 | |
if kind == 2: | |
for i in [(0,2),(1,3)]: | |
next_maps = check_map(maps, i, y, x) | |
detecting(next_maps, cctvs, idx+1) | |
# 상하, 좌우 각각의 값을 total_amount에 넣는다 | |
# 다음 탐색 | |
if kind == 3: | |
for i in [(0,1),(1,2),(2,3),(3,0)]: | |
next_maps = check_map(maps, i, y, x) | |
detecting(next_maps, cctvs, idx+1) | |
# 90도 방향으로 4번. 탐색값 | |
if kind == 4: | |
for i in [(0,1,2),(1,2,3),(2,3,0),(3,0,1)]: | |
next_maps = check_map(maps, i, y, x) | |
detecting(next_maps, cctvs, idx+1) | |
# 사방향 중 하나 빼고 탐색. | |
if kind == 5: | |
# 사방향 전체 탐색 | |
next_maps = check_map(maps, (0,1,2,3), y, x) | |
detecting(next_maps, cctvs, idx+1) | |
detecting(maps, cctvs, 0) | |
print(mins) |
반응형
'프로그래밍 > 코딩테스트 문제풀이' 카테고리의 다른 글
[Python] 백준 2493. 탑 (0) | 2020.01.31 |
---|---|
[Python] 백준 17140. 이차원 배열과 연산 (0) | 2020.01.29 |
[Python] 프로그래머스. 여행경로 (Level 3) (0) | 2020.01.24 |
[Python] 프로그래머스. 도둑질 (Level 4) (0) | 2020.01.22 |
[Python] 프로그래머스. 스티커 모으기(2) (Level 4) (0) | 2020.01.18 |