습관처럼

백준 15683 - 감시 본문

Algorithms/BOJ

백준 15683 - 감시

dev.wookii 2020. 5. 1. 23:00

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×1크기의 정사각형으로 나누어져 있는 N×M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는 5가지 종류가 있다.

CCTV는 감시할 수 있는 방향에 있는 칸 전체를 감시할 수 있다. 사무실에는 벽이 있는데, CCTV는 벽을 통과할 수 없다. CCTV가 감시할 수 없는 영역은 사각지대라고 한다. 

 

RULE

- 총 5개의 CCTV 가 존재하는데, 각 CCTV 는 감시할 수 있는 방향이 다르다.

- CCTV 는 90도 회전이 가능하다.

- CCTV 는 벽을 통과할 수 없지만, CCTV 는 통과할 수 있다.

 

 

 

* 1번 CCTV - (오른쪽), (위쪽), (왼쪽), (아래쪽) => 4가지

2번 CCTV - (왼쪽, 오른쪽), (위쪽, 아래쪽) => 2가지

3번 CCTV - (위쪽, 오른쪽), (오른쪽, 아래쪽), (아래쪽, 왼쪽), (왼쪽, 위쪽) => 4가지

4번 CCTV - (왼쪽, 위쪽, 오른쪽), (위쪽, 오른쪽, 아래쪽), (오른쪽, 아래쪽, 왼쪽), (아래쪽, 왼쪽, 위쪽) => 4가지

5번 CCTV - (왼쪽, 위쪽, 오른쪽, 아래쪽) => 1가지

 

 

 

접근 방법


위의 룰을 기반으로 Dfs와 Brute Focefh 차근차근 구현했습니다. 구현에 까다롭지는 않지만 그렇다고 쉽지는 않다고 생각합니다.

좋은 문제인거 같아요 화이팅~

 

 

코드


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

using namespace std;

typedef struct{
    int y,x;
    int dir;
    int type;
}Camera;
vector<Camera>vec;
vector<Camera>vec_temp;
int r,c;
vector<vector<int> >map(8,vector<int>(8,0));
int numofCam,ans=100;
// int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}}; //동-남-서-북

void move(int dir,int y,int x){
    switch(dir){
        
        //북
        case 0:
            for(int i=y-1;i>=0;i--){
                if(map[i][x]==6) break;
                if(map[i][x]==0) map[i][x]=-1; //cctv 감시 완료
            }
            break;
        
        //동
        case 1:
            for(int j=x+1;j<c;j++){
                if(map[y][j]==6) break;
                if(map[y][j]==0) map[y][j]=-1; 
            }
            break;
            
        //남
        case 2:
            if(dir==2){
                for(int i=y+1;i<r;i++){
                    if(map[i][x]==6) break;
                    if(map[i][x]==0) map[i][x]=-1;
                }
            }
            break;
            
        //서
        case 3:
            for(int j=x-1;j>=0;j--){
                if(map[y][j]==6) break;
                if(map[y][j]==0) map[y][j]=-1;
            }
            
    }
}
void dfs(int count){
    if(count==numofCam){
        int cnt=0;
        for(int i=0;i<r;i++){
            for(int j=0;j<c;j++){
                if(map[i][j]==0)cnt++;
            }
        }
        ans = min(ans,cnt);
        return;
    }
    int cury = vec[count].y;
    int curx = vec[count].x;
    int curtype = vec[count].type;
    
    vector<vector<int> >map_temp = map;
    switch (curtype){

        case 1:
            for(int dir=0;dir<4;dir++){
                move(dir,cury,curx);
                dfs(count+1);
                map=map_temp;
            }
            break;
        case 2:
            for(int dir=0;dir<4;dir++){
                move(dir,cury,curx);
                move(dir+2,cury,curx);
                dfs(count+1);
                map=map_temp;
            }
            break;
        case 3:
            for(int dir=0;dir<4;dir++){
                move(dir,cury,curx);
                move((dir+1)%4,cury,curx);
                dfs(count+1);
                map=map_temp;
            }
            break;
        case 4:
            for(int dir=0;dir<4;dir++){
                move(dir,cury,curx);
                move((dir+1)%4,cury,curx);
                move((dir+2)%4,cury,curx);
                dfs(count+1);
                map=map_temp;

            }
            break;
        case 5:
            for(int dir=0;dir<4;dir++){
                move(dir,cury,curx);
            }
            dfs(count+1);
            break;
    }
    

}
int main(){
    cin>>r>>c;
    for(int i=0;i<r;i++){
        for(int j=0;j<c;j++){
            cin>>map[i][j];
            if(map[i][j]>=1 && map[i][j]<=5){
                Camera cam;
                cam.y= i; cam.x =j;
                cam.dir = 0;
                cam.type = map[i][j];
                vec.push_back(cam);
            }
        }
    }
    numofCam =vec.size();
    dfs(0);
    cout<<ans<<"\n";
    return 0;
}

funny algorithm ^-^

'Algorithms > BOJ' 카테고리의 다른 글

백준 15685 - 드래곤 커브  (0) 2020.05.06
백준 17779 - 게리맨더링2  (0) 2020.05.05
백준 14891 - 톱니바퀴  (0) 2020.04.30
백준 3023 - 마술사 이민혁  (0) 2020.04.13
백준 14890 - 경사로  (0) 2020.04.13