본문 바로가기
백준 알고리즘/구현

감시 C++

by paysmile 2021. 10. 22.

https://www.acmicpc.net/problem/15683

 

15683번: 감시

스타트링크의 사무실은 1×1크기의 정사각형으로 나누어져 있는 N×M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는 5가지 종류가 있다. 각 CCTV가 감

www.acmicpc.net

#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>

using namespace std;
int n, m;
int map[10][10];
vector<pair<int, int>> camera;
vector<int> dir;
int answer = 98765321;
int visited[10][10][4];
int tmp_v[10][10];
struct MOVE { int x, y; };
MOVE mv[4] = { {0,1},{-1,0}, {0,-1},{1,0} };//오른쪽, 위, 왼쪽, 아래

void copyvisited() {
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++) {
            tmp_v[i][j] = map[i][j];
        }
    }
}

void CalArea() {
    copyvisited();

    for (int i = 0; i < dir.size(); i++) {
        int mi = camera[i].first;
        int mj = camera[i].second;
        int cctv = map[mi][mj];
        int d = dir[i];

        tmp_v[mi][mj] = 1;
        for (int j = 0; j < 4; j++) {
            int movei = mi;
            int movej = mj;
            if (visited[mi][mj][j] == 1) {
                int direction = j + d;
                while (direction >= 4) direction %= 4;

                while (true) {
                    movei = movei + mv[direction].x;
                    movej = movej + mv[direction].y;

                    if (!(movei >= 0 && movei < n && movej >= 0 && movej < m)) break;

                    if (map[movei][movej] == 6) break;

                    tmp_v[movei][movej] = 1;
                }
            }
        }
    }
}

void Rec() {
    int value = 0;

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (tmp_v[i][j] == 0) value++;
        }
    }

    answer = min(answer, value);
}

void ChooseDir() {
    if (dir.size() == camera.size()) {
        CalArea();
        Rec();
        return;
    }

    for (int i = 0; i < 4; i++) {
        dir.push_back(i);
        ChooseDir();
        dir.pop_back();
    }
}

int main(void) {
    cin >> n >> m;

    memset(visited, -1, sizeof(visited));

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> map[i][j];
            if (map[i][j] > 0 && map[i][j] < 6) {
                camera.push_back({ i,j });

                if (map[i][j] == 1) {
                    visited[i][j][0] = 1;
                }
                else if (map[i][j] == 2) {
                    visited[i][j][0] = 1;
                    visited[i][j][2] = 1;
                }
                else if (map[i][j] == 3) {
                    visited[i][j][0] = 1;
                    visited[i][j][1] = 1;
                }
                else if (map[i][j] == 4) {
                    visited[i][j][0] = 1;
                    visited[i][j][1] = 1;
                    visited[i][j][2] = 1;
                }
                else if (map[i][j] == 5) {
                    visited[i][j][0] = 1;
                    visited[i][j][1] = 1;
                    visited[i][j][2] = 1;
                    visited[i][j][3] = 1;
                }
            }
        }
    }

    ChooseDir();
    cout << answer << endl;
}

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

스타트와 링크 C++  (0) 2021.10.22
경사로 C++  (0) 2021.10.22
톱니바퀴 C++  (0) 2021.10.22
치킨 배달 C++  (0) 2021.10.21
드래곤 커브 C++  (0) 2021.10.21