-
BOJ 17142 연구소 3알고리즘 2023. 8. 23. 21:30
#BOJ 17142 연구소 3
17142번: 연구소 3
인체에 치명적인 바이러스를 연구하던 연구소에 승원이가 침입했고, 바이러스를 유출하려고 한다. 바이러스는 활성 상태와 비활성 상태가 있다. 가장 처음에 모든 바이러스는 비활성 상태이고,
www.acmicpc.net
#풀이
저번에 풀었던 연구소 문제와 많이 비슷하다.
일단 문제가 조금 애매 하게 나와있어서 왜 틀렸는지 몰랐다.
먼저 활성화된 바이러스가 번식을 하는데 비활성화된 바이러스를 만나면 활성화를 시킨다.
이렇게 바이러스가 벽이 아닌 모든 칸에 바이러스가 있을 때 까지 걸리는 최소 시간을 구하는 문제이다.
바이러스 중에서 m개를 골라서 활성화 시켜야 하기 때문에 그냥 간단하게 백트래킹을 사용해야 한다고 생각이 들었다. 그래서 조합으로 풀면 쉽게 풀릴 것 같아 next_permutation을 사용했다.
활성화된 바이러스를 번식시켜서 bfs를 사용하여 모든 곳에 방문을 했을 때 시간을 구하면 된다.
이 때 주의해야 할 것이 비활성화된 바이러스다.
비활성화 바이러스가 벽에 붙어 있다면 굳이 방문할 필요가 없다.
하지만 벽이 아닌 중앙에 있다면 활성을 시켜서 조금 더 빠르게 모든 칸을 방문해야 한다.
그래서 나는 그냥 벽일 때만 큐에 넣지 않고 가장 큰 시간을 구하기 전에 바이러스를 모두 -1 로 대입하고 했다.
#코드
#include<iostream> #include<algorithm> #include<queue> #include<vector> using namespace std; int dx[4] = { 1,-1,0,0 }; int dy[4] = { 0,0,1,-1 }; int arr[51][51]; int n, m; vector<pair<int, int>> b_p; int p[251]; int min_ans = 0x7f7f7f7f; void solved() { do { queue<pair<int, int>> q; int vis[51][51] = { 0, }; for (int i = 1; i <= b_p.size(); i++) { if (p[i] == 1) { q.push({b_p[i-1]}); vis[b_p[i - 1].first][b_p[i - 1].second] = -1; } } while (!q.empty()) { // bfs auto cur = q.front(); q.pop(); for (int i = 0; i < 4; i++) { int x = dx[i] + cur.first; int y = dy[i] + cur.second; if (x < 1 || y < 1 || x >n || y>n || arr[x][y] == 1 || vis[x][y] != 0) continue; // 비활성화된 바이러스는 활성화됨 if (vis[cur.first][cur.second] == -1) // 활성화된 바이러스일 경우 vis[x][y] = 1; else vis[x][y] = vis[cur.first][cur.second] + 1; q.push({ x,y }); } } int max_time = 0; bool flag = 0; for (int i = 0; i < b_p.size(); i++) { // 모든 바이러스는 -1 최소 시간을 구하는데 사용하지 않음 vis[b_p[i].first][b_p[i].second] = -1; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (vis[i][j] == 0 && arr[i][j] != 1) { // 빈칸인데 방문을 안했을 때 flag = 1; break; } if (max_time < vis[i][j]) { max_time = vis[i][j]; } } if (flag) { // 모든 빈칸이 바이러스가 아닐 때 break; } } if ( flag == 0 && min_ans > max_time) { min_ans = max_time; } } while (next_permutation(p+1, p+1+b_p.size())); // 바이러스중에서 m개 선택 (조합) } int main() { ios::sync_with_stdio(0); cin.tie(0); cin >> n >> m; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { cin >> arr[i][j]; if (arr[i][j] == 2) b_p.push_back({ i,j }); } } for (int i = 0; i < m; i++) { p[b_p.size() - i] = 1; } solved(); if (min_ans == 0x7f7f7f7f) min_ans = -1; cout << min_ans << '\n'; return 0; }
'알고리즘' 카테고리의 다른 글
BOJ 17837 : 새로운 게임 2 (0) 2023.08.27 BOJ 17779 : 게리맨더링 2 (0) 2023.08.25 BOJ 17143 : 낚시왕 (0) 2023.08.23 BOJ 17140 : 이차원 배열과 연산 (0) 2023.08.21 BOJ 17144: 미세먼지 안녕! (0) 2023.08.20