알고리즘과 자료구조/백준

BOJ 14502 연구소

bggbr 2020. 1. 4. 16:30

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

 

14502번: 연구소

인체에 치명적인 바이러스를 연구하던 연구소에서 바이러스가 유출되었다. 다행히 바이러스는 아직 퍼지지 않았고, 바이러스의 확산을 막기 위해서 연구소에 벽을 세우려고 한다. 연구소는 크기가 N×M인 직사각형으로 나타낼 수 있으며, 직사각형은 1×1 크기의 정사각형으로 나누어져 있다. 연구소는 빈 칸, 벽으로 이루어져 있으며, 벽은 칸 하나를 가득 차지한다.  일부 칸은 바이러스가 존재하며, 이 바이러스는 상하좌우로 인접한 빈 칸으로 모두 퍼져나갈 수 있다.

www.acmicpc.net

문제 해결전략

 

연구소 문제는 DFS와 BFS를 혼합한 문제이다.

문제 해결의 순서

DFS를 통해 map의 빈 공간에 벽 3개 배치 -> temp 배열에 map을 복사 -> map에 바이러스 퍼뜨리기 -> 안전지대 갯수 세기 -> map에 temp를 복사 -> 다시 DFS를 통해 벽 3개 배치 -> 최대 안전지대 갯수 갱신

 

소스

#include <iostream>
#include <queue>
using namespace std;
#define endl "\n"
const int dy[4] = {-1, 0, 1, 0};
const int dx[4] = {0, 1, 0, -1};
int map[8][8];
int n, m;
int totalNum = -1;

struct virus{
    int y, x;
};
virus v[10];

void check(){
    int cnt = 0;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            if(map[i][j]) continue;
            cnt++;
        }
    }
    totalNum = max(totalNum, cnt);
}

void copy(int tmp[8][8], int origin[8][8]){
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            tmp[i][j] = origin[i][j];
        }
    }
}

void bfs(){
    queue<pair<int, int>> q;
    for(int i = 0; i < 10; i++){
        if(map[v[i].y][v[i].x] != 2) break;
        q.push({v[i].y, v[i].x});
    }
    while(!q.empty()){
        int y = q.front().first;
        int x = q.front().second;
        q.pop();
        for(int i = 0; i < 4; i++){
            int ny = y + dy[i];
            int nx = x + dx[i];
            if(ny < 0 || ny >= n || nx < 0 || nx >= m || map[ny][nx]) continue;
            map[ny][nx] = 2;
            q.push({ny, nx});
        }
    }
    check();
}

void dfs(int cnt){
    if(cnt == 3){
        int temp[8][8];
        copy(temp, map);
        bfs();
        copy(map, temp);
        return;
    }
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            if(map[i][j]) continue;
            map[i][j] = 1;
            dfs(cnt + 1);
            map[i][j] = 0;
        }
    }
}
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    cin >> n >> m;
    int idx = 0;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            cin >> map[i][j];
            if(map[i][j] == 2){
                v[idx].y = i; v[idx].x = j;
                idx++;
            }
        }
    }
    dfs(0);
    cout << totalNum;
}

'알고리즘과 자료구조 > 백준' 카테고리의 다른 글

BOJ 17822 원판 돌리기  (0) 2020.10.15
BOJ 15686 치킨 배달  (0) 2020.01.05
BOJ 3190 뱀  (0) 2019.12.31
BOJ 14501 퇴사  (0) 2019.12.30
BOJ 1389 케빈 베이컨의 6단계 법칙  (0) 2019.12.27