[BOJ] 17142 : 연구소 3

17142 : 연구소 3

풀이

2019 삼성전자 SW역량테스트 오후시험 2번 변형문제.

BFS/DFS

전형적인 삼성전자 SW역량테스트 문제이다. DFS로 조합짜고 BFS로 탐색한다.

연구소 2번문제 먼저 풀어보면 좋다.

다만 2번풀고 3번을 풀때, 3번문제에서 ‘모든 비활성화 바이러스가 활성화가 된 상태’라는 조건을 하나 더 추가하는것을 빠뜨리기 쉽다.

그리고 비활성화인 바이러스를 활성화 시키는 경우는 시간으로 치지 않는다.

그래서 큐에 push하기전에 비활성화 바이러스인지 아닌지 조건을 검사했고,

활성화 시키는 경우가 아닐때만 max시간을 갱신하도록 했다.

코드

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <cstring>
#include <queue>
using namespace std;

//0빈칸 1벽 2바이러스놓을수있는위치
int arr[51][51];
//퍼지는 거리 측정겸 체크
int flood[51][51];
//n연구소사이즈 m바이러스개수
int n, m;
int ans = -1;
int zeroNum = 0;
const int dx[] = { 0,1,0,-1 };
const int dy[] = { 1,0,-1,0 };
//바이러스놓을수있는 위치 저장 벡터
vector<pair<int, int>> v;
vector<int> pick;
//flood fill로 최소시간 찾기
void bfs() {
    memset(flood, -1, sizeof(flood));
    int maxNum = 0;
    int cnt = 0;
    int activeCnt = 0;
    queue<pair<int, int>> q;
    for (int i = 0; i < m; i++) {
        int idx = pick[i];
        q.push({v[idx].first,v[idx].second});
        flood[v[idx].first][v[idx].second] = 0;
    }
    while (!q.empty()) {
        int x = q.front().first;
        int y = q.front().second;
        q.pop();
        for (int dir = 0; dir < 4; dir++) {
            int nx = x + dx[dir];
            int ny = y + dy[dir];
            if (nx >= 0 && nx < n&&ny >= 0 && ny < n&&arr[nx][ny] !=1 && flood[nx][ny] == -1) {
                if (arr[nx][ny] == 2) {
                    q.push({ nx,ny });
                    flood[nx][ny] = flood[x][y] + 1;
                    activeCnt++;
                }
                else {
                    q.push({ nx,ny });
                    flood[nx][ny] = flood[x][y] + 1;
                    cnt++;
                    if (flood[nx][ny]>maxNum)
                        maxNum = flood[nx][ny];
                }
            }
        }
    }
    //두가지를 만족하는 경우에만 시간을 갱신한다.
    //1.바이러스가 모든 빈공간에 퍼졌을것
    //2.모든 비활성화 바이러스에 방문했을것
    if (zeroNum == cnt && activeCnt==(v.size()-m)) {
        if (ans == -1 || ans > maxNum)
            ans = maxNum;
    }
}

void go(int i,int cnt) {
    if (cnt == m) {
        bfs();
        return;
    }
    if (i >= v.size()) {
        return;
    }
    pick.push_back(i);
    go(i + 1, cnt + 1);
    pick.pop_back();
    go(i + 1, cnt);
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> arr[i][j];
            if (arr[i][j] == 2) {
                v.push_back({i,j});
            }
            else if (arr[i][j] == 0) {
                zeroNum++;
            }
        }
    }
    go(0,0);
    cout << ans;
    return 0;
}
Written on April 21, 2019