2206번: 벽 부수고 이동하기
N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 최단 경로
www.acmicpc.net
- 미로를 탐험하면서 벽을 부쉈는지에 대한 상태에 대해 알고 있어야 문제를 풀 수 있었다.
- 이는 visited[MAX_SIZE+1][MAX_SIZE+1][2] 의 형태로 3차원의 인덱스가 0일경우 부순적 없음, 1일경우 부순적 있음으로 생각하여 BFS 코드를 구현하면 된다.
- 헤더 파일 중 #include <limits.h>를 써서 INT_MAX를 사용하고 BFS의 반환 값을 min 값으로 변경하며 사용했다. (이거를 사용하지 않고 9999 이런식으로 했다가 생각해보니 1000 * 1000 에서는 더 큰 숫자가 나올 수 있더라)
더보기
#include <iostream>
#include <queue>
#include <string.h>
#include <limits.h>
// def
#define MAX_SIZE 1000
#define debug_m 0
// struct
struct Info
{
Info(int _r = 0, int _c = 0, int _sc = 0, bool _isB = false)
{
r = _r;
c = _c;
score = _sc;
isBroken = _isB;
}
int r;
int c;
int score;
bool isBroken;
};
// global
char board[MAX_SIZE + 1][MAX_SIZE + 1];
bool visited[MAX_SIZE + 1][MAX_SIZE + 1][2]; // [][][0] : 부수적 없음, [][][1] : 부순적 있음
int direction[4][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; // 상 하 좌 우
// method
bool CheckingValid(int n, int m, int N, int M);
int BFS(int N, int M);
int main()
{
// 2206 - 벽 부수고 이동하기
// init
setbuf(stdout, NULL);
for (int i = 0; i < MAX_SIZE + 1; i++)
{
memset(board[i], 0, sizeof(MAX_SIZE + 1));
}
// input
int N, M;
N = M = 0;
(void)scanf("%d %d", &N, &M);
for (int n = 0; n < N; n++)
{
char buf[MAX_SIZE + 1] = { 0, };
(void)scanf("%s", &buf);
memcpy(board[n], buf, sizeof(buf));
}
// bfs
const int answer = BFS(N, M);
// print
printf("%d", answer);
return 0;
}
bool CheckingValid(int n, int m, int N, int M)
{
bool retValue = true;
if ((0 > n || N <= n) || (0 > m || M <= m))
retValue = false;
return retValue;
}
int BFS(int N, int M)
{
int retValue = INT_MAX;
std::queue<Info> que;
que.push(Info(0, 0, 1, false));
visited[0][0][0] = visited[0][0][1] = true;
while (!que.empty())
{
Info info = que.front();
que.pop();
#if debug_m
printf("\n[%s] { info (%d, %d), sc : %d, isBroken : %d}\n",
__FUNCTION__, info.r, info.c, info.score, info.isBroken);
#endif
if ((N - 1 == info.r) && (M - 1 == info.c))
{
retValue = retValue < info.score ? retValue : info.score;
}
for (int d = 0; d < 4; d++)
{
int nextR = info.r - direction[d][0];
int nextC = info.c - direction[d][1];
const bool bIsValid = CheckingValid(nextR, nextC, N, M);
if (true == bIsValid)
{
const char board_data = board[nextR][nextC];
if ('0' == board_data)
{
if (false == info.isBroken && false == visited[nextR][nextC][0])
{
que.push(Info(nextR, nextC, info.score + 1, false));
visited[nextR][nextC][0] = true;
}
else if (true == info.isBroken && false == visited[nextR][nextC][1])
{
que.push(Info(nextR, nextC, info.score + 1, true));
visited[nextR][nextC][1] = true;
}
}
else
{
if (false == info.isBroken && false == visited[nextR][nextC][1])
{
que.push(Info(nextR, nextC, info.score + 1, true));
visited[nextR][nextC][1] = true;
}
}
}
}
}
if (INT_MAX == retValue)
retValue = -1;
return retValue;
}
'Coding Problem > 백준' 카테고리의 다른 글
[백준] 1504 - 특정한 최단 경로 (0) | 2021.01.14 |
---|---|
[백준] 1753 - 최단 경로 (0) | 2021.01.03 |
[백준] 1697 - 숨박꼭질 (0) | 2020.12.07 |
[백준] 7569 - 토마토 (0) | 2020.12.04 |
[백준] 7576 - 토마토 (0) | 2020.12.04 |