728x90
반응형
  • 문제

지훈이는 미로에서 일을 한다. 지훈이를 미로에서 탈출하도록 도와주자!

미로에서의 지훈이의 위치와 불이 붙은 위치를 감안해서 지훈이가 불에 타기전에 탈출할 수 있는지의 여부, 그리고 얼마나 빨리 탈출할 수 있는지를 결정해야한다.

지훈이와 불은 매 분마다 한칸씩 수평또는 수직으로(비스듬하게 이동하지 않는다) 이동한다.

불은 각 지점에서 네 방향으로 확산된다.

지훈이는 미로의 가장자리에 접한 공간에서 탈출할 수 있다.

지훈이와 불은 벽이 있는 공간은 통과하지 못한다.

  • 입력

입력의 첫째 줄에는 공백으로 구분된 두 정수 R과 C가 주어진다. 단, 1 ≤ R, C ≤ 1000 이다. R은 미로 행의 개수, C는 열의 개수이다.

다음 입력으로 R줄동안 각각의 미로 행이 주어진다.

각각의 문자들은 다음을 뜻한다.

  • #: 벽
  • .: 지나갈 수 있는 공간
  • J: 지훈이의 미로에서의 초기위치 (지나갈 수 있는 공간)
  • F: 불이 난 공간

J는 입력에서 하나만 주어진다.

  • 출력

지훈이가 불이 도달하기 전에 미로를 탈출 할 수 없는 경우 IMPOSSIBLE 을 출력한다.

지훈이가 미로를 탈출할 수 있는 경우에는 가장 빠른 탈출시간을 출력한다.

  • 예제 입력
4 4
####
#JF#
#..#
#..#
  • 예제 출력
3
  • 접근방식

bfs로 불의 최단거리와 병훈이의 최단거리를 비교해나간다. + 불은 1개 이상 존재함 (1개만 존재하는게 아닐수도 있음), 불이 없는 경우도 존재하기 때문에 높은 수의 변수를 지정해놓음

  • 코드
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <stack>
#include <queue>
#include <cstring>

using namespace std;

// 가장 빠른 탈출시간 -> bfs
// 불은 네방향으로 확산
// 불의 최단거리와 병훈이의 최단거리 비교
// ret = person_check[y][x] 부분 C6385오류 발생

const int INF = 987654321;
char a[1004][1004];
int n, m, sx, sy, dx[4] = { -1,0,1,0 }, dy[4] = { 0,-1,0,1 }, ret, y, x;
int fire_check[1004][1004], person_check[1004][1004];
bool in(int a, int b) 
{
	return 0 <= a && a < n && 0 <= b && b < m;
}

int main() 
{
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	queue<pair<int, int>> q;
	cin >> n >> m;
	fill(&fire_check[0][0], &fire_check[0][0] + 1004 * 1004, INF);
	for (int i = 0; i < n; i++)
    {
		for (int j = 0; j < m; j++)
        {
			cin >> a[i][j];
			if (a[i][j] == 'F')
            {
				fire_check[i][j] = 1; q.push({ i, j });
			}
			else if (a[i][j] == 'J')
            {
				sy = i; sx = j;
			}
		}
	}

	while (q.size()) // 불의 최단거리 먼저 구하기
    {
		tie(y, x) = q.front();
		q.pop();
		for (int i = 0; i < 4; i++)
        {
			int ny = y + dy[i];
			int nx = x + dx[i];
			if (!in(ny, nx)) continue;
			if (fire_check[ny][nx] != INF || a[ny][nx] == '#') continue;
			fire_check[ny][nx] = fire_check[y][x] + 1;
			q.push({ ny, nx });
		}
	}

	person_check[sy][sx] = 1;
	q.push({ sy,sx });
	while (q.size())
    {
		int y = q.front().first;
		int x = q.front().second;
		q.pop();
		if (x == m - 1 || y == n - 1 || x == 0 || y == 0) // 빠져 나오는 부분
        {
			ret = person_check[y][x];
			break;
		}
		for (int i = 0; i < 4; i++)
        {
			int ny = y + dy[i];
			int nx = x + dx[i];
			if (!in(ny, nx)) continue;
			if (person_check[ny][nx] || a[ny][nx] == '#') continue;
			if (fire_check[ny][nx] <= person_check[y][x] + 1) continue;
			person_check[ny][nx] = person_check[y][x] + 1;
			q.push({ ny, nx });
		}
	}
	if (ret != 0) cout << ret << "\n";
	else cout << "IMPOSSIBLE \n";
	return 0;
}
 

4179번: 불!

입력의 첫째 줄에는 공백으로 구분된 두 정수 R과 C가 주어진다. 단, 1 ≤ R, C ≤ 1000 이다. R은 미로 행의 개수, C는 열의 개수이다. 다음 입력으로 R줄동안 각각의 미로 행이 주어진다. 각각의 문자

www.acmicpc.net

728x90
반응형

'C++ > BOJ' 카테고리의 다른 글

[C++]/백준 16337번 괄호 추가하기  (1) 2024.02.28
[C++]/백준 12869번 뮤탈리스크  (0) 2024.02.28
[C++]/백준 16234번 인구 이동  (0) 2024.02.20
[C++]/백준 2589번 보물섬  (0) 2024.02.20
[C++]/백준 17298번 오큰수  (0) 2023.01.20

+ Recent posts