https://www.acmicpc.net/problem/2151
2151번: 거울 설치
첫째 줄에 집의 크기 N (2 ≤ N ≤ 50)이 주어진다. 다음 N개의 줄에는 N개의 문자로 집에 대한 정보가 주어진다. ‘#’는 문이 설치된 곳으로 항상 두 곳이며, ‘.’은 아무 것도 없는 것으로 빛은
www.acmicpc.net
문제를 잘 이해하지 못해 애먹었던 문제이다.
처음에는 문이 가장자리에만 존재하는 줄 알았고, 그다음에는 양면거울이란 게 뭘 의미하는지 몰랐다.
일단 문제 풀이는 다음과 같다.
문제의 조건에서 항상 문끼리는 빛이 서로 도달할 수 있다고 했으므로, 아무 문에서 출발해 bfs를 수행한다.
여기서 주의해야 할 점은 방문 배열의 정의이다.
단순히 x, y 좌표만 저장하게 되면 어떤 방향으로 빛이 왔는지 몰라서 다음 탐색 시에 더 이상 진행할 수 없게 된다.
따라서 visit[i][j][k] = k방향으로 i행, j열에 도착했을 때 설치한 최소 거울 개수로 정의하였다.
그런데 여기서 주의할 점이 하나 더 있다.
보통 가중치가 없는 bfs에서는 방문 순서가 항상 최단 거리이다. 그래서 한 번 방문한 곳은 다시 방문하지 않아도 된다.
하지만 이 문제는 최단 거리를 구하는 것이 아니라 해당 좌표로 이동할 때 설치한 최소 거울의 개수를 구하는 것이므로 더 적은 개수의 거울로 해당 좌표를 방문할 수 있을 때, 갱신할 필요가 있다.
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
char map[50][50];
int visit[50][50][4], n;
int x[4] = { 0,1,0,-1 };
int y[4] = { 1,0,-1,0 };
int main() {
cin >> n;
int sx = -1, sy, dx, dy;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> map[i][j];
if (map[i][j] == '#') {
if (sx == -1) {
sx = i; sy = j;
}
else {
dx = i; dy = j;
}
}
visit[i][j][0] = visit[i][j][1] = visit[i][j][2] = visit[i][j][3] = 2500;
}
}
queue<pair<pair<int, int>, int>> q; //i, j, dir
for (int i = 0; i <= 3; i++) {
q.push({ {sx,sy},i });
visit[sx][sy][i] = 0;
}
while (!q.empty()) {
int a = q.front().first.first;
int b = q.front().first.second;
int dir = q.front().second;
q.pop();
int nx = a + x[dir];
int ny = b + y[dir];
if (nx >= 0 && nx < n && ny >= 0 && ny < n && map[nx][ny] != '*') {
if (map[nx][ny] == '!') {
for (int i = 1; i <= 3; i += 2) {
if (visit[nx][ny][(dir + i) % 4] > visit[a][b][dir] + 1) {
visit[nx][ny][(dir + i) % 4] = visit[a][b][dir] + 1;
q.push({ {nx,ny},(dir + i) % 4 });
}
}
}
if (visit[nx][ny][dir] > visit[a][b][dir]) {
q.push({ {nx,ny},dir });
visit[nx][ny][dir] = visit[a][b][dir];
}
}
}
int ans = -1;
for (int i = 0; i < 4; i++) {
if (visit[dx][dy][i] == -1)continue;
if (ans == -1 || visit[dx][dy][i] < ans)ans = visit[dx][dy][i];
}
cout << ans;
}
'ps' 카테고리의 다른 글
[백준] 1981 - 배열에서 이동 (0) | 2022.08.18 |
---|---|
[백준] 10835 - 카드게임 (0) | 2022.08.18 |
[백준] 2342 - Dance Dance Revolution (0) | 2022.08.17 |
[백준] 2842 - 집배원 한상덕 (0) | 2022.08.17 |
[백준] 11967 - 불켜기 (0) | 2022.08.17 |
댓글