https://www.acmicpc.net/problem/1194
1194번: 달이 차오른다, 가자.
첫째 줄에 미로의 세로 크기 N과 가로 크기 M이 주어진다. (1 ≤ N, M ≤ 50) 둘째 줄부터 N개의 줄에 미로의 모양이 주어진다. 같은 타입의 열쇠가 여러 개 있을 수 있고, 문도 마찬가지이다. 그리고,
www.acmicpc.net
보통 BFS라면, visit 같은 방문 배열에 체크를 해두고 다시는 방문하지 않는 것이 특징인데,
이러한 문제는 특정한 곳을 방문한 뒤에 다른 특정한 곳을 방문할 수 있다라는 것이 특이한 점이다.
문제를 잘 보면, N 제한은 50이고 열쇠는 최대 6개이다. 생각보다 제한이 작다.
BFS 문제에서 가장 고려해야 할 사항 중 하나는 바로 방문 배열을 어떻게 구성할 것인가 이다.
이 문제에서는 열쇠의 개수가 작으므로,
열쇠를 하나도 가지고 있지 않은 경우부터, 모든 열쇠를 가지고 있는 경우의 수를 모두 더해도 2 ^ 6 = 64 밖에 되지 않는다.
따라서 이 점을 이용할 것이다.
visit[a][b][c] = c의 조합으로 a행 b열을 방문
즉, c = 0이라면 열쇠를 하나도 가지고 있지 않은 상태에서 방문한다는 뜻이고,
c = 63이라면 모든 열쇠를 가지고 방문한다는 뜻이다.
구현은 비트마스킹으로 생각보다 쉽게 구현할 수 있었다.
#include <iostream>
#include <queue>
#include <tuple>
using namespace std;
int n, m;
char map[50][50];
int visit[50][50][64];
int x[4] = { 0,0,1,-1 };
int y[4] = { 1,-1,0,0 };
queue<tuple<int, int, int>> q;
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> map[i][j];
if (map[i][j] == '0') {
q.push({ i,j,0 });
visit[i][j][0] = 1;
}
}
}
while (!q.empty()) {
int a, b, c;
tie(a, b, c) = q.front();
q.pop();
if (map[a][b] == '1') {
cout << visit[a][b][c] - 1;
return 0;
}
for (int k = 0; k < 4; k++) {
int nx = a + x[k];
int ny = b + y[k];
if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
if (map[nx][ny] != '#') {
if (map[nx][ny] >= 'a' && map[nx][ny] <= 'z') {
if (!visit[nx][ny][c | (1 << (map[nx][ny] - 'a'))]) {
q.push({ nx,ny,c | (1 << (map[nx][ny] - 'a')) });
visit[nx][ny][c | (1 << (map[nx][ny] - 'a'))] = visit[a][b][c] + 1;
}
}
else if (map[nx][ny] >= 'A' && map[nx][ny] <= 'Z') {
if (c & (1 << (map[nx][ny] - 'A')) && !visit[nx][ny][c]) {
q.push({ nx,ny,c });
visit[nx][ny][c] = visit[a][b][c] + 1;
}
}
else { // 출구
if (!visit[nx][ny][c]) {
q.push({ nx,ny,c });
visit[nx][ny][c] = visit[a][b][c] + 1;
}
}
}
}
}
}
cout << -1;
}
'ps' 카테고리의 다른 글
[백준] 1941 - 소문난 칠공주 (0) | 2022.07.27 |
---|---|
[백준] 1103 - 게임 (0) | 2022.07.27 |
[백준] 1285 - 동전 뒤집기 (0) | 2022.07.26 |
[백준] 2613 - 숫자구슬 (0) | 2022.07.26 |
[백준] 7570 - 줄 세우기 (0) | 2022.07.25 |
댓글