본문 바로가기

BOJ/C++

[BOJ] 15683. 감시

[문제]

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

[풀이]

 

1)  cctv가 한번에 탐색할 수 있는 방향은 정해져 있다. 

1번 - 1

2번 - 2

3번 - 2

4번 - 3

5번 - 4

 

2) cctv가 여러대 있을 때 각각 탐색할 수 있는 방향을 정해서 그 때의 최소 사각지대를 구하는 것이다. (각 cctv마다 모든 방향을 탐색한 후에 사각지대를 구하는 게 아님)

 

3) 칸에 적힌 수가 0인 칸은 빈칸이고 사각지대가 될 수 있는 칸이다. 1-5 : cctv, 6 - 벽 

 

4) cctv는 서로 통과할 수 있다. 

 

5) 두 가지 정수 배열을 만든다. 

tvCnt =>  각 cctv마다 한번에 탐색할 수 있는 방향의 개수 (만약 1번 cctv와 5번이 있을 때 1번은 한 방향, 5번은 4방향을 한번에 탐색해야하기 때문에)

 

tvDir => 각 cctv마다 탐색할 수 있는 방향 지정(상 우 하 좌 ) 

 

6) 재귀 호출을 사용한다. (cctv의 개수가 정해져 있고 완탐을 하기 위해서 )

dfs( 현재 탐색할 cctv의 인덱스 , 남은 사각지대의 개수 )

 

6-1) 종료 조건 => 모든 cctv를 탐색했을 때 (남은 사각지대의 개수를 리턴한다.

 

6-2) 현재 맵의 상태를 저장하는 게 중요하다. (c_map을 생성해서 맵의 상태를 보존한다.)

 

6-3) 두 개의 for 반복문을 사용한다. (1 => 상 하 좌 우 / 2 -> 각 cctv마다 한번에 탐색할 수 있는 방향의 개수만큼 반복)

탐색할 수 있는 방향은 4개이기 때문에  dir = (j+i) % 4 함으로서 올바른 범위 내의 방향을 탐색할 수 있도록 한다. 

 

6-4) 현재 나아갈 수 있는 방향이 맵의 범위를 벗어나지 않고 벽을 만나지 않았다면 계속 나아간다. (벽을 만날 때까지)

=> 사각지대의 개수를 줄여주고, 사각지대가 아닌 칸은 -1로 만들어준다. (맵의 변형 -> cctv의 방향을 바꿀 때마다 맵을 복원해줘야 하는 이유이다.)

 

6-5) 현재 cctv가 탐색할 수 있는 모든 방향을 탐색했다면 재귀호출을 해서 다른 cctv도 탐색하여 최소 사각지대를 구한다. 

'BOJ > C++' 카테고리의 다른 글

[BOJ] 17140. 이차원 배열과 연산  (0) 2019.08.04
[BOJ] 17142. 연구소3  (0) 2019.08.04
[BOJ] 14891. 톱니바퀴  (0) 2019.08.02
[BOJ] 14890. 경사로  (0) 2019.08.02
[BOJ] 14500. 테트로미노  (0) 2019.08.02