티스토리 뷰
17142번: 연구소 3
인체에 치명적인 바이러스를 연구하던 연구소에 승원이가 침입했고, 바이러스를 유출하려고 한다. 바이러스는 활성 상태와 비활성 상태가 있다. 가장 처음에 모든 바이러스는 비활성 상태이고
www.acmicpc.net
> 문제 설명
문제
인체에 치명적인 바이러스를 연구하던 연구소에 승원이가 침입했고, 바이러스를 유출하려고 한다. 바이러스는 활성 상태와 비활성 상태가 있다. 가장 처음에 모든 바이러스는 비활성 상태이고, 활성 상태인 바이러스는 상하좌우로 인접한 모든 빈 칸으로 동시에 복제되며, 1초가 걸린다. 승원이는 연구소의 바이러스 M개를 활성 상태로 변경하려고 한다.
연구소는 크기가 N×N인 정사각형으로 나타낼 수 있으며, 정사각형은 1×1 크기의 정사각형으로 나누어져 있다. 연구소는 빈 칸, 벽, 바이러스로 이루어져 있으며, 벽은 칸 하나를 가득 차지한다. 활성 바이러스가 비활성 바이러스가 있는 칸으로 가면 비활성 바이러스가 활성으로 변한다.
예를 들어, 아래와 같이 연구소가 생긴 경우를 살펴보자. 0은 빈 칸, 1은 벽, 2는 바이러스의 위치이다.
2 0 0 0 1 1 0
0 0 1 0 1 2 0
0 1 1 0 1 0 0
0 1 0 0 0 0 0
0 0 0 2 0 1 1
0 1 0 0 0 0 0
2 1 0 0 0 0 2
M = 3이고, 바이러스를 아래와 같이 활성 상태로 변경한 경우 6초면 모든 칸에 바이러스를 퍼뜨릴 수 있다. 벽은 -, 비활성 바이러스는 *, 활성 바이러스는 0, 빈 칸은 바이러스가 퍼지는 시간으로 표시했다.
* 6 5 4 - - 2
5 6 - 3 - 0 1
4 - - 2 - 1 2
3 - 2 1 2 2 3
2 2 1 0 1 - -
1 - 2 1 2 3 4
0 - 3 2 3 4 *
시간이 최소가 되는 방법은 아래와 같고, 4초만에 모든 칸에 바이러스를 퍼뜨릴 수 있다.
0 1 2 3 - - 2
1 2 - 3 - 0 1
2 - - 2 - 1 2
3 - 2 1 2 2 3
3 2 1 0 1 - -
4 - 2 1 2 3 4
* - 3 2 3 4 *
연구소의 상태가 주어졌을 때, 모든 빈 칸에 바이러스를 퍼뜨리는 최소 시간을 구해보자.
입력
첫째 줄에 연구소의 크기 N(4 ≤ N ≤ 50), 놓을 수 있는 바이러스의 개수 M(1 ≤ M ≤ 10)이 주어진다.
둘째 줄부터 N개의 줄에 연구소의 상태가 주어진다. 0은 빈 칸, 1은 벽, 2는 바이러스를 놓을 수 있는 위치이다. 2의 개수는 M보다 크거나 같고, 10보다 작거나 같은 자연수이다.
출력
연구소의 모든 빈 칸에 바이러스가 있게 되는 최소 시간을 출력한다. 바이러스를 어떻게 놓아도 모든 빈 칸에 바이러스를 퍼뜨릴 수 없는 경우에는 -1을 출력한다.
풀이
틀린 풀이 1. 선택한 바이러스에 대해 bfs()를 할 때 끝까지 돌려주고(벽은 -1로 체크) 마지막에 남은 0 있는지 확인하는 방식으로 풀었는데
그럼 탐색 못하는 쪽 벽은 -1로 처리가 안되서 bfs해줄 때마다 벽은 초기화를 해줘야 했다. (효율 안좋을 것 같아서 안해봄)
틀린 풀이 2. 처음 인풋 받았을 때, 각 바이러스에 대해서 퍼질 수 있는 곳 정보 map를 만들어줬다.
그리고 조합했을 때, M개의 바이러스 map을 합치고 거기서 최대시간값을 구하면 될 것 같다고 생각했는데
합치는 게 제대로 안되고, 아마 '비활성 바이러스가 활성 바이러스 만날 때' 그 부분을 체크를 잘 못해준 것 같다.
바이러스 고를 수 있는 조합에 대해 골라준다. (combination 함수)
고른 바이러스 수(count)가 M이 됐다면 bfs 시작
-> bfs
queue에 선택한 바이러스 위치들을 넣어준다.
고른 바이러스 위치의 시간은 0 (tempMap 배열에 저장, visited정보로 사용)
bfs 돌리면서 빈칸인 곳을 탐색해줄 때 count 해서 초기맵의 빈칸 개수랑 같아질 때 return 한다.
#define MAXN 51
#define MAXM 11
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <string.h>
using namespace std;
int N, M;
int map[MAXN][MAXN];
vector<pair<int, int> > virus;
bool selected[MAXM] = {false, };
int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int minTime = 987654321;
int blankCnt = 0;
int tempMap[MAXN][MAXN];
void initialize(){
cin>>N>>M;
for(int i=0; i<N; i++){
for(int j=0; j<N; j++){
cin>>map[i][j];
if(map[i][j] == 2){
map[i][j] = -2;
virus.push_back({i, j});
}
else if(map[i][j] == 0) {
blankCnt++;
}
}
}
memset(selected, false, sizeof(selected));
}
void bfs(){
queue<pair<int, int>> q;
int cnt = blankCnt;
memset(tempMap, -1, sizeof(tempMap));
for(int i=0; i<virus.size(); i++){
if(selected[i] == true){
pair<int, int> v = virus[i];
q.push(v);
tempMap[v.first][v.second] = 0;
}
}
while(!q.empty()){
int nowx = q.front().first;
int nowy = q.front().second;
q.pop();
for(int i=0; i<4; i++){
int nextx = nowx + dir[i][0];
int nexty = nowy + dir[i][1];
if(nextx>=0 && nextx<N && nexty>=0 && nexty<N){
if(map[nextx][nexty] != 1 && tempMap[nextx][nexty] == -1){
q.push({nextx, nexty});
tempMap[nextx][nexty] = tempMap[nowx][nowy] + 1;
if(map[nextx][nexty] == 0){
cnt--;
}
if(cnt == 0 ){
minTime = min(minTime, tempMap[nextx][nexty]);
return;
}
}
}
}
}
return;
}
void combination(int depth, int count){
if(count == M){
bfs();
return;
}
for(int i=depth; i<virus.size(); i++){
if(selected[i] == false){
selected[i] = true;
combination(i+1, count+1);
selected[i] = false;
}
}
return;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
initialize();
if(blankCnt == 0){
cout<<"0"<<"\n";
return 0;
}
combination(0, 0);
if(minTime == 987654321){
cout<<"-1\n";
}
else{
cout<<minTime<<"\n";
}
return 0;
}
'CS > Algorithm' 카테고리의 다른 글
[백준-삼성SW역량테스트 기출] 17140번. 이차원 배열과 연산 C++ (0) | 2021.04.17 |
---|---|
[백준-삼성SW역량테스트 기출] 17779번. 게리맨더링 2 C++ (0) | 2021.04.17 |
[백준-삼성SW역량테스트 기출] 17825번. 주사위 윷놀이 C++ (0) | 2021.04.17 |
[백준-삼성SW역량테스트 기출] 5373번. 큐빙 C++ (0) | 2021.03.27 |
[백준-삼성SW역량테스트 기출] 16236번. 아기 상어 C++ (0) | 2021.03.26 |
- Total
- Today
- Yesterday
- C++
- 웨이팅후기
- typescript
- error
- beakjoon
- 하단탭
- 브루트포스 알고리즘
- 알고리즘
- 지킬앤하이드
- 삼성sw역량테스트
- react-native-make
- 백준
- DFS
- 시뮬레이션
- 일기
- Problem Solving
- DP
- algorithm
- 삼성SW역량테스트 기출
- 기출
- react navigation
- rn
- 뉴욕여행
- application
- react native
- 구현
- react-native
- Android
- BFS
- problem
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |