문제
홍익이는 사악한 마법사의 꾐에 속아 N x M 미로 (Hx, Hy) 위치에 떨어졌다. 다행히도 홍익이는 마법사가 만든 미로의 탈출 위치(Ex, Ey)를 알고 있다. 하지만 미로에는 곳곳에 마법사가 설치한 벽이 있어 홍익이가 탈출하기 어렵게 하고 있다.
홍익이는 마법사의 연구실에서 훔친 지팡이가 있어, 벽을 길로 만들 수 있다. 그렇지만, 안타깝게도 마법의 지팡이는 단 한 번만 사용할 수 있다.
이때, 홍익이를 도와 미로에서 탈출할 수 있는지 알아보고, 할 수 있다면 가장 빠른 경로의 거리 D는 얼마인지 알아보자.
인접한 칸으로 이동하는데 똑같은 시간이 들고, 벽을 부수는 데 시간이 걸리지 않는다.
입력
N M
Hx Hy
Ex Ey
N X M 행렬
- 2 ≤ N ≤ 1000, 2 ≤ M ≤ 1000
- 1 ≤ Hx, Hy, Ex, Ey ≤ 1000
- (Hx, Hy)≠ (Ex, Ey)
- 행렬은 0과 1로만 이루어져 있고, 0이 빈 칸, 1이 벽이다.
출력
D (탈출 할 수 없다면, -1을 출력한다.)
예제 입력 1
5 6
1 1
5 6
0 1 1 1 0 0
0 1 1 0 0 0
0 1 0 0 1 0
0 1 0 0 1 0
0 0 0 1 1 0
예제 출력 1
11
알고리즘 분류
- 그래프 탐색
풀이
그냥 벽뚫기 문제이다.
visited[N][M][2] 배열을 선언해서, (N, M)을 마법의 지팡이를 사용하지 않았을 때 visited[N][M][1]와 사용했을 때 visited[N][M][0]를 구분해서 방문했음을 표시해준다.
코드
#include <iostream>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define FIRST cin.tie(NULL); cout.tie(NULL); ios::sync_with_stdio(false);
#define MAX 1005
#define LL long long
#define INF 2e9
using namespace std;
struct INFO {
int Y, X, Cost;
bool Flag;
};
int N, M, HY, HX, EY, EX;
int MAP[MAX][MAX];
bool visited[MAX][MAX][2];
int moveY[4] = { -1,0,1,0 };
int moveX[4] = { 0,-1,0,1 };
int D = INF;
void BFS(int Y, int X) {
queue<INFO> Q;
visited[Y][X][1] = true;
INFO Info = { Y,X,0,true };
Q.push(Info);
while (!Q.empty()) {
INFO CurInfo = Q.front();
Q.pop();
if ((CurInfo.Y == EY) && (CurInfo.X == EX)) {
D = min(D, CurInfo.Cost);
return;
}
for (int i = 0; i < 4; i++) {
int nextY = CurInfo.Y + moveY[i];
int nextX = CurInfo.X + moveX[i];
if ((nextY >= 1) && (nextY <= N) && (nextX >= 1) && (nextX <= M) && (!visited[nextY][nextX][CurInfo.Flag])) {
if (MAP[nextY][nextX] == 0) {
visited[nextY][nextX][CurInfo.Flag] = true;
INFO newInfo = { nextY,nextX,CurInfo.Cost + 1,CurInfo.Flag };
Q.push(newInfo);
}
else if (MAP[nextY][nextX] == 1) {
if (CurInfo.Flag) {
visited[nextY][nextX][false] = true;
INFO newInfo = { nextY,nextX,CurInfo.Cost + 1,false };
Q.push(newInfo);
}
}
}
}
};
}
int main() {
FIRST
cin >> N >> M;
cin >> HY >> HX;
cin >> EY >> EX;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
cin >> MAP[i][j];
}
}
BFS(HY, HX);
if (D == INF) {
cout << -1 << "\n";
}
else {
cout << D << "\n";
}
return 0;
}
'BOJ > Gold' 카테고리의 다른 글
[BOJ/Gold 4] 백준 16973 직사각형 탈출(C++) (0) | 2022.02.07 |
---|---|
[BOJ/Gold 4] 백준 16397 탈출(C++) (0) | 2022.02.07 |
[BOJ/Gold 5] 백준 22352 항체 인식(C++) (0) | 2022.02.07 |
[BOJ/Gold 5] 백준 15971 두 로봇(C++) (0) | 2022.02.06 |
[BOJ/Gold 5] 백준 14395 4연산(C++) (0) | 2022.02.06 |