관리 메뉴

어읽로꾸거

BOJ 17141 연구소 2 본문

알고리즘

BOJ 17141 연구소 2

어읽로꾸거 2019. 9. 13. 16:04

백준 17141 링크

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

 

17141번: 연구소 2

인체에 치명적인 바이러스를 연구하던 연구소에 승원이가 침입했고, 바이러스를 유출하려고 한다. 승원이는 연구소의 특정 위치에 바이러스 M개를 놓을 것이고, 승원이의 신호와 동시에 바이러스는 퍼지게 된다. 연구소는 크기가 N×N인 정사각형으로 나타낼 수 있으며, 정사각형은 1×1 크기의 정사각형으로 나누어져 있다. 연구소는 빈 칸, 벽으로 이루어져 있으며, 벽은 칸 하나를 가득 차지한다. 일부 빈 칸은 바이러스를 놓을 수 있는 칸이다. 바이러스는 상하좌우로

www.acmicpc.net

풀이

순열을 이용해서 바이러스를 배치하는 경우의 수를 갈라주고 따지고 각각의 경우에서 BFS를 돌려주면 끝?(아마) 순열은 DFS로 구했음.

 

자대에 오고 사지방에서 처음으로 풀어보는 문제였음. 거의 4개월만에 푸는거라 감각을 다시 익히고 하는데 힘들었음. (Dev 말고 VS 쓸 수 있으면 좋겠다) 동기에게 백준을 알려주고 몇몇 문제를 추천해 주었다. 이상 전달끝.

코드

#include <stdio.h>
#include <iostream>
#include <queue>
using namespace std;

int n,m,o_map[52][52], t_map[52][52],v_avail[10][2], v_count;
int v_select[10][2];
int min2=0x7fffffff, cannot_reach;
int xl[] = {0,0,-1,1};
int yl[] = {1,-1,0,0};
queue < pair<int,int> > q;

//room where never visited is marked -1
//wall is makred -2
//virus start point is 0

int boundary_check(int x, int y){
	if(1<=x&&x<=n&&1<=y&&y<=n&&t_map[x][y]==-1)
		return 1;
	else
		return 0;
}

void set_tempmap(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			t_map[i][j]=o_map[i][j];
		}
	}
	for(int i=0;i<m;i++){
		t_map[v_select[i][0]][v_select[i][1]]=0;
		q.push({v_select[i][0],v_select[i][1]});
	}
}

void sim_start(){
	int x, y, nx, ny, max, reach;
	reach = 0;
	max=0;
	while(!q.empty()){
		x=q.front().first;
		y=q.front().second;
		q.pop();
		for(int i=0;i<4;i++){
			nx=x+xl[i];
			ny=y+yl[i];
			if(boundary_check(nx,ny)){
				t_map[nx][ny]=t_map[x][y]+1;
				max = t_map[nx][ny]>max?t_map[nx][ny]:max;
				q.push({nx,ny});
			}
		}
	}
	//check if there is place never visited
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(t_map[i][j] == -1){
				max = 0x7fffffff;
			}
		}
	}
	min2 = max<min2?max:min2;
}

void DFS(int idx, int cnt){
	if(cnt == m){
		set_tempmap();
		sim_start();
	}
	else{
		if(idx==v_count){
			return;
		}
		else{
			DFS(idx+1,cnt);
			v_select[cnt][0]=v_avail[idx][0];
			v_select[cnt][1]=v_avail[idx][1];
			DFS(idx+1,cnt+1);
		}
	}
}

int main() {
	//freopen("input.txt","r",stdin);
	
	scanf("%d %d",&n,&m);
	
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			scanf("%d", &o_map[i][j]);
			if(o_map[i][j] == 0){
				o_map[i][j] = -1;
			}
			else if(o_map[i][j] == 1){
				o_map[i][j] = -2;
			}
			else if(o_map[i][j] == 2){
				v_avail[v_count][0]=i;
				v_avail[v_count++][1]=j;
				o_map[i][j] = -1;
			}
		}
	}
	
	DFS(0,0);
	
	if(min2==0x7fffffff){
		cout<<-1;
	}
	else{
		cout<<min2;
	}
}

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

BOJ 14613 너의 티어는?  (0) 2019.09.15
BOJ 1038 감소하는 수  (0) 2019.09.15
BOJ 6186 Best Grass  (0) 2019.04.23
BOJ 13549 숨바꼭질3  (0) 2019.04.22
BOJ 6118 숨바꼭질  (0) 2019.04.19