본문 바로가기
알고리즘 공부

백준 3055번 탈출 [BFS]

by kjwkjw 2020. 3. 25.

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

 

3055번: 탈출

문제 사악한 암흑의 군주 이민혁은 드디어 마법 구슬을 손에 넣었고, 그 능력을 실험해보기 위해 근처의 티떱숲에 홍수를 일으키려고 한다. 이 숲에는 고슴도치가 한 마리 살고 있다. 고슴도치는 제일 친한 친구인 비버의 굴로 가능한 빨리 도망가 홍수를 피하려고 한다. 티떱숲의 지도는 R행 C열로 이루어져 있다. 비어있는 곳은 '.'로 표시되어 있고, 물이 차있는 지역은 '*', 돌은 'X'로 표시되어 있다. 비버의 굴은 'D'로, 고슴도치의 위치는 'S'로 나

www.acmicpc.net

 

 

입력에 사용된 문자들

 

R: 숲의 높이

C: 숲의 넓이

. : 비어있는 곳(고슴도치가 이동가능한 곳)

* : 물이 차있는 지역(고슴도치가 이동 불가능한 지역)

X: 돌(고슴도치가 이동불가능한 지역, 물이 차지 못하는 지역)

S: 고슴도치 위치

D: 비버의 굴(목적지)

 

출력

 

이동할 수 있는 가장 빠른 시간을 출력한다.

이동 불가능하다면 "KAKTUS"를 출력한다.

 

문제 풀이방식

 

1. 물이 차있는 지역은 1분마다 인접한(상,하,좌,우) 곳으로 번진다.

2. 1분이 지나면 고슴토치가 이동할 수 있는 모든방향(상,하,좌,우)으로 이동한다. (단, 돌과 물이 차있는 방향으로 이동하지 못한다.)

3. 고슴도치가 목적지에 다다르면 그때의 시간을 리턴한다.

 

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int r,c;
int sy,sx;
int dy,dx;
char arr[51][51];
int chk[51][51];
vector< pair<int,int> >v;

void spray(){
	int len = v.size();
	for(int i = 0; i < len; i++){
		if(v[i].first+1<r&&arr[v[i].first+1][v[i].second]!='D'&&arr[v[i].first+1][v[i].second]!='X'&&arr[v[i].first+1][v[i].second]!='*'){
			arr[v[i].first+1][v[i].second]='*';
			v.push_back(make_pair(v[i].first+1,v[i].second));
		}
		if(v[i].first-1>=0&&arr[v[i].first-1][v[i].second]!='D'&&arr[v[i].first-1][v[i].second]!='X'&&arr[v[i].first-1][v[i].second]!='*'){
			arr[v[i].first-1][v[i].second]='*';
			v.push_back(make_pair(v[i].first-1,v[i].second));
		}
		if(v[i].second+1<c&&arr[v[i].first][v[i].second+1]!='D'&&arr[v[i].first][v[i].second+1]!='X'&&arr[v[i].first][v[i].second+1]!='*'){
			arr[v[i].first][v[i].second+1]='*';
			v.push_back(make_pair(v[i].first,v[i].second+1));
		}
		if(v[i].second-1>=0&&arr[v[i].first][v[i].second-1]!='D'&&arr[v[i].first][v[i].second-1]!='X'&&arr[v[i].first][v[i].second-1]!='*'){
			arr[v[i].first][v[i].second-1]='*';
			v.push_back(make_pair(v[i].first,v[i].second-1));
		}
	}
}
int play(){
	queue< pair<int, int> > pq;
	pq.push(make_pair(sy,sx));
	int y,x;
	int cnt = 0;
	while(!pq.empty()){
		y = pq.front().first;
		x = pq.front().second;
		if(y==dy&&x==dx) return chk[y][x];
		pq.pop();
		if(chk[y][x]==cnt){
			spray();
			cnt++;
		}
		if(y+1<r&&chk[y+1][x]==0&&(arr[y+1][x]=='D'||arr[y+1][x]=='.')){
			pq.push(make_pair(y+1,x));
			chk[y+1][x]=chk[y][x] + 1;
			arr[y+1][x] = 'S';
		}
		if(y-1>=0&&chk[y-1][x]==0&&(arr[y-1][x]=='D'||arr[y-1][x]=='.')){
			pq.push(make_pair(y-1,x));
			chk[y-1][x]=chk[y][x] + 1;
			arr[y-1][x] = 'S';
		}
		if(x+1<c&&chk[y][x+1]==0&&(arr[y][x+1]=='D'||arr[y][x+1]=='.')){
			pq.push(make_pair(y,x+1));
			chk[y][x+1]=chk[y][x] + 1;
			arr[y][x+1] = 'S';
		}
		if(x-1>=0&&chk[y][x-1]==0&&(arr[y][x-1]=='D'||arr[y][x-1]=='.')){
			pq.push(make_pair(y,x-1));
			chk[y][x-1]=chk[y][x] + 1;
			arr[y][x-1] = 'S';
		}
	}
	return -1;
}

int main(int argc, char const *argv[])
{
	ios::sync_with_stdio(false); 
    cin.tie(NULL); 
    cout.tie(NULL);
    cin>>r>>c;

    for(int i = 0; i < r; i++){
    	for(int j = 0; j < c; j++){
    		cin>>arr[i][j];
    		if(arr[i][j]=='S'){
    			sy = i;
    			sx = j;
    		} else if(arr[i][j]=='D'){
    			dy = i;
    			dx = j;
    		} else if(arr[i][j]=='*'){
    			v.push_back(make_pair(i,j));
    		}
    	}
    }

    int ans = play();

    if(ans==-1) cout<<"KAKTUS"<<"\n";
    else cout<<ans<<"\n";

	return 0;
}

 

 

 

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

백준 1009 분산처리  (0) 2020.05.16
백준 1008 A/B  (0) 2020.05.16
백준 1003 피보나치 함수 [DP]  (0) 2020.05.16
백준 1001 A-B  (0) 2020.05.16
백준 1000 A+B  (0) 2020.05.16

댓글