ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [BOJ]17142번 연구소3
    알고리즘/BOJ 2020. 8. 17. 23:38

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

     

    17142번: 연구소 3

    인체에 치명적인 바이러스를 연구하던 연구소에 승원이가 침입했고, 바이러스를 유출하려고 한다. 바이러스는 활성 상태와 비활성 상태가 있다. 가장 처음에 모든 바이러스는 비활성 상태이고

    www.acmicpc.net

    아이디어

    1, 활성화시킬 바이러스들을 next_permutation함수를 이용하여 택하고 bfs방법을 이용하여 퍼지는 시간을 구하였다.

     

    2, 백트레킹 방식을 이용하여 탐색을 하다가 현재 구해놓은 최소 시간 이상 탐색을 실행할 시 실행을 중지하고 다음 케이스를 bfs방식으로 탐색을 하였다.

     

    3, 문제의 조건에서 모든 영역에 바이러스가 있으면 종료가 됨으로(비활성화 된 바이러스도 바이러스다.) 빈칸의 수만큼 탐색을 진행할 시 탐색을 중지하고 시간을 구하였다.

     

    #include <cstdio>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    typedef struct virus {
    	int r;
    	int c;
    	int depth;
    }virus;
    
    int N, M;
    
    int map[51][51];
    int visited[51][51];
    
    int dr[4] = { 0,1,0,-1 };
    int dc[4] = { 1,0,-1,0 };
    
    int vector_size;
    
    vector<virus> viruses;
    vector<int> group;
    
    int aim = 0;
    int ans = 1000000;
    
    
    void simulation(queue<virus> *q) {
    	virus search;
    	virus insert;
    	int nr, nc;
    	int res = 0;
    	int check = 0;
    	int occupy_count = 0;
    
    	while (!q->empty()) {
    		search = q->front();
    		q->pop();
    		
    
    		if (occupy_count == aim) { check = 2; break; }
    		
    		for (int i = 0; i < 4; i++) {
    			nr = search.r + dr[i];
    			nc = search.c + dc[i];
    
    
    			if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;
    
    
    			if (map[nr][nc] != 1 && visited[nr][nc] == 0) {
    				insert.r = nr;
    				insert.c = nc;
    				insert.depth = search.depth + 1;
    				q->push(insert);
    				visited[nr][nc] = 1;
    				if (map[nr][nc] == 0) occupy_count++;
    				if (insert.depth >= ans) { check = 1;  break; }
    				else res = insert.depth;
    			}
    		}
    		if (check == 1) break;
    	}
    
    	while (!q->empty()) {
    		q->pop();
    	}
    
    	if (check == 2) {
    		if (ans > res) ans = res;
    	}
    
    }
    
    int main() {
    
    	virus insert;
    	queue<virus> q;
    	scanf("%d %d", &N, &M);
    
    
    	for (int i = 0; i < N; i++) {
    		for (int j = 0; j < N; j++) {
    			scanf("%d", &map[i][j]);
    
    			if (map[i][j] == 2){
    				insert.r = i;
    				insert.c = j;
    				insert.depth = 0;
    				viruses.push_back(insert);
    			}
    
    			if (map[i][j] == 0) aim++;
    						
    		}
    	}
    
    	vector_size = viruses.size();
    
    
    	for (int i = 0; i < vector_size; i++) {
    		if (i < M) {
    			group.push_back(1);
    		}
    		else {
    			group.push_back(0);
    		}
    	}
    
    	sort(group.begin(), group.end());
    
    
    	do {
    		
    		memset(visited, 0, sizeof(visited));
    
    		for (int i = 0; i < vector_size; i++) {
    			if (group[i] == 1) {
    				q.push(viruses[i]);
    				visited[viruses[i].r][viruses[i].c] = 1;
    			}
    		}
    
    		simulation(&q);
    
    	} while (next_permutation(group.begin(), group.end()));
    
    	if (ans != 1000000) {
    		printf("%d\n", ans);
    	}
    	else {
    		printf("%d\n", -1);
    	}
    
    
    
    	return 0;
    }

    '알고리즘 > BOJ' 카테고리의 다른 글

    2805번 아기 상어  (0) 2024.03.28
    10816 숫자 카드 2  (0) 2024.03.26
    [BOJ]17143번 낚시왕  (0) 2020.08.17
    [BOJ]16235번 나무 제태크  (0) 2020.08.16
    [BOJ]16236번 아기 상어  (0) 2020.08.16
Designed by Tistory.