아무코딩

[백준 15683] 감시 본문

알고리즘/백준

[백준 15683] 감시

동 코 2020. 3. 27. 23:09

문제 풀이

CCTV 번호마다 감시하는 방법이 다르다. 하지만 1번카메라를 통해서 모두 똑같이 구현할수 있다.

1번카메라를 통해 벽을 만나는 계산하는 함수를 구한뒤

나머지에 중복 적용 해준다.

 

소스코드

더보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
typedef struct Camera {
    int row;
    int col;
    int version;
    Camera(int r,int c,int v){
        row = r;
        col = c;
        version = v;
    }
}Camera;
 
 
int N, M;
int Map[8][8];
int min_cnt = 64;
vector<Camera> cam;
int dir_row[4= { 1,0,-1,0 };
int dir_col[4= { 0,1,0,-1 };
 
void MapCopy(int (*a)[8], int (*b)[8]) {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            a[i][j] = b[i][j];
        }
    }
}
void cam_1(Camera camera, int dir) {//1번방식
    int next_row = camera.row;
    int next_col = camera.col;
    next_row += dir_row[dir];
    next_col += dir_col[dir];
    for (; next_row >= 0 && next_col >= 0 && next_row < N&&next_col < M;) {
 
 
        switch (Map[next_row][next_col]) {
        case 0:
            Map[next_row][next_col] = -1;
            break;
        case 6://벽만나면 아예 함수 종료
            return;
        default:
            break;
        }
        next_row += dir_row[dir];
        next_col += dir_col[dir];
    }
}
 
void dfs(int num) {
    int cnt;
    int temp[8][8];
    if (num >= cam.size()) {
        cnt = 0;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                if (Map[i][j] == 0)
                    cnt++;
            }
        }
        min_cnt = min(min_cnt, cnt);
        return;
    }
    MapCopy(temp, Map);
    switch (cam[num].version) {
    case 1:
        for (int j = 0; j < 4; j++) {
            cam_1(cam[num], j);
            dfs(num + 1);
            MapCopy(Map, temp);
        }
        break;
    case 2:
        for (int j = 0; j < 2; j++) {
            cam_1(cam[num], j);
            cam_1(cam[num], (j + 2) % 4);
            dfs(num + 1);
            MapCopy(Map, temp);
        }
        break;
    case 3:
        for (int j = 0; j < 4; j++) {
            cam_1(cam[num], j);
            cam_1(cam[num], (j + 1) % 4);
            dfs(num + 1);
            MapCopy(Map, temp);
        }
        break;
    case 4:
        for (int j = 0; j < 4; j++) {
            cam_1(cam[num], j);
            cam_1(cam[num], (j + 1) % 4);
            cam_1(cam[num], (j + 2) % 4);
            dfs(num + 1);
            MapCopy(Map, temp);
        }
        break;
    case 5:
        for (int j = 0; j < 4; j++) {
            cam_1(cam[num], j);
        }
        dfs(num + 1);
        MapCopy(Map, temp);
        break;
    }
}
 
int main() {
    scanf("%d %d"&N, &M);
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            scanf("%d"&Map[i][j]);
            if (Map[i][j] >= 1 && Map[i][j] <= 5)
                cam.push_back(Camera(i, j, Map[i][j]));
        }
    }
 
    dfs(0);
    printf("%d\n", min_cnt);
}
 

 

문제 링크 : 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

 

'알고리즘 > 백준' 카테고리의 다른 글

[백준 14503] 로봇청소기  (0) 2020.04.06
[백준 16638] 괄호 추가하기 2  (1) 2020.03.31
[백준 12094] 2048(hard)  (0) 2020.03.29
[백준 17136] 색종이 붙이기  (0) 2020.03.17
[백준 1525] 퍼즐  (0) 2020.03.13
Comments