-
[BOJ] #15683 _ 감시Problem Solving/BOJ 2019. 10. 20. 23:39
[감시] 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를 이용하여 각 cctv가 볼 수 있는 4가지 방향의 모든 경우의 수를 고려해주었다.
모든 cctv의 방향이 결정되면, 각 cctv에 맞게 감시하고 사각지대의 수를 구해 최소 값을 갱신하였다.
(cctv의 좌표는 cctv배열에 저장해주었다.)
[ 소스 코드 ]
#include <cstdio> #include <algorithm> #define MAX 8 using namespace std; int dx[] = { 0,1,0,-1 }, dy[] = { -1,0,1,0 }; int N, M; int office[MAX][MAX], chk[MAX][MAX], cctv_d[MAX]; int minVal = 99999999, cctv_num; pair<int, int> cctv[MAX]; void solve(int idx, int d); int count_space(); void copy_arr(); int main() { scanf("%d %d", &N, &M); for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { scanf("%d", &office[i][j]); if (office[i][j] > 0 && office[i][j] < 6) cctv[cctv_num++] = make_pair(i, j); } } for(int i=0; i<4; i++) solve(0, i); printf("%d\n", minVal); return 0; } void solve(int idx, int d) { cctv_d[idx] = d; if (idx + 1 >= cctv_num) { minVal = min(minVal, count_space()); return; } for (int i = 0; i < 4; i++) solve(idx + 1, i); } int count_space() { int count = 0, tmp_x, tmp_y; copy_arr(); for (int idx = 0; idx < cctv_num; idx++) { tmp_x = cctv[idx].second; tmp_y = cctv[idx].first; while (1) { tmp_x += dx[cctv_d[idx]]; tmp_y += dy[cctv_d[idx]]; if (tmp_x < 0 || tmp_y < 0 || tmp_x >= M || tmp_y >= N) break; if (office[tmp_y][tmp_x] == 6) break; chk[tmp_y][tmp_x] = 1; } if (office[cctv[idx].first][cctv[idx].second] == 2) { tmp_x = cctv[idx].second; tmp_y = cctv[idx].first; while (1) { tmp_x -= dx[cctv_d[idx]]; tmp_y -= dy[cctv_d[idx]]; if (tmp_x < 0 || tmp_y < 0 || tmp_x >= M || tmp_y >= N) break; if (office[tmp_y][tmp_x] == 6) break; chk[tmp_y][tmp_x] = 1; } } else { for (int i = 1; i < office[cctv[idx].first][cctv[idx].second] - 1; i++) { tmp_x = cctv[idx].second; tmp_y = cctv[idx].first; cctv_d[idx]++; if (cctv_d[idx] >= 4) cctv_d[idx] = 0; while (1) { tmp_x += dx[cctv_d[idx]]; tmp_y += dy[cctv_d[idx]]; if (tmp_x < 0 || tmp_y < 0 || tmp_x >= M || tmp_y >= N) break; if (office[tmp_y][tmp_x] == 6) break; chk[tmp_y][tmp_x] = 1; } } } } for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { if (chk[i][j] == 0) count++; } } return count; } void copy_arr() { for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) chk[i][j] = office[i][j]; } }
'Problem Solving > BOJ' 카테고리의 다른 글
[BOJ] #15685 _ 드래곤 커브 (0) 2019.10.22 [BOJ] #15684 _ 사다리 조작 (0) 2019.10.21 [BOJ] #14890 _ 경사로 (0) 2019.10.20 [BOJ] #14500 _ 테트로미노 (0) 2019.10.20 [BOJ] #13458 _ 시험 감독 (0) 2019.10.20 댓글