리뷰
https://www.acmicpc.net/problem/25417
왠진 모르겠는데 조건문에 ||와 &&를 섞어서 작성 후 제출했었다 어이없게 두번을 틀렸다.
전역 변수
- lst : 맵 정보를 저장할 2차원 배열
- v : 방문 정보를 체크할 2차원 배열
- Pos : 현재 위치 x, y와 소요 시간 t를 정의할 구조체, t를 기준으로 오름차순 정렬한다.
- dx, dy : 4방향 탐색을 위한 방향 배열
함수
1. bfs
int bfs(int sx, int sy)
너비 우선 탐색을 통해 출발지 부터 도착지 까지 이동 하는 최소 시간을 구하는 함수
- 매개 변수로 시작 위치의 좌표 sx, sy를 전달 받는다.
- Pos타입의 우선순위 큐 pq를 초기화 하고, 초기 위치 sx, sy와 소요 시간 0을 push해준다.
- v배열에 시작 위치를 방문처리를 진행해 준다.
- pq가 빌 때 까지 while 루프를 수행하고, 매 루프마다 요소를 한개씩 꺼내어 준다.
- 기저 조건으로 목표 위치에 도달한 경우 소요 시간 ct를 리턴해 준다.
- 4방향 탐색을 진행하고, 맵의 범위 내에 있으며, 방문 처리되어 있지 않고, -1이 아니라면 이동을 진행한다.
- 이동 후엔 방문처리 후 이동한 위치와 소요 시간을 증가시킨 후 pq에 push해준다.
- 이후 해당 방향으로 쭉 진행을 이어준다.
- 맵의 범위를 벗어난 경우 벗어나기 전의 위치에 방문처리가 되어있지 않다면 이동을 진행한다.
- -1을 만난 경우 만나기 전의 위치에 방문처리가 되어있지 않다면 이동을 진행한다.
- 이동한 위치가 맵 상에서 7이고, 해당 위치에 방문처리가 되어있지 않다면 이동을 진행한다.
- 각 케이스에 해당하는 위치에 방문처리 및 pq에 push를 진행하고, break처리해 준다.
- while 루프가 종료될 때 까지 기저 조건에 도달하지 못한다면 -1을 리턴해 준다.
2. print
void print(int x, int y, int t)
디버깅용 함수
문제풀이
- 5 * 5 맵 정보를 lst배열에 입력 받아준다.
- 시작 위치의 좌표 sx, sy에 값을 입력 받고, bfs함수에 매개변수로 전달하여 값을 리턴 받는다.
- 리턴받은 값을 출력해 준다.
트러블 슈팅
- 예제는 다 맞는데 제출 시 14%에서 계속 틀리게 되었다.
- 범위 체크를 해주는 로직에서 || 한개를 &&로 작성해 준게 원인이었다, 고치고 나니 AC를 받았다.
참고 사항
- 그냥 queue를 사용해 주니 한 방향으로 쭉 진행하였을 때 그리디하지 못한 것 같아 pq로 변경해 주었다.
정답 코드
#include<iostream>
#include<queue>
using namespace std;
int lst[5][5];
bool v[5][5];
struct Pos {
int x, y, t;
bool operator<(const Pos& other) const {
return t > other.t;
}
};
int dx[] = { 1, -1, 0, 0 };
int dy[] = { 0, 0, 1, -1 };
void print(int x, int y, int t) {
for (int i = 0; i < 5; ++i) {
for (int j = 0; j < 5; ++j) {
if (x == i && y == j) cout << 8 << " ";
else cout << lst[i][j] << " ";
}
cout << "\n";
}
cout << x << " " << y << " " << t << "\n";
}
int bfs(int sx, int sy) {
priority_queue<Pos> pq;
pq.push({ sx, sy, 0 });
v[sx][sy] = true;
while (!pq.empty()) {
Pos pos = pq.top(); pq.pop();
int cx = pos.x, cy = pos.y, ct = pos.t;
//print(cx, cy, ct);
if (lst[cx][cy] == 1) return ct;
for (int i = 0; i < 4; ++i) {
int nx = cx + dx[i], ny = cy + dy[i], nt = ct + 1;
if (0 <= nx && nx < 5 && 0 <= ny && ny < 5 && !v[nx][ny] && lst[nx][ny] != -1) {
v[nx][ny] = true;
pq.push({ nx, ny, nt });
while (1) {
if (0 > nx || nx >= 5 || 0 > ny || ny >= 5) {
int nnx = nx - dx[i], nny = ny - dy[i];
//cout << nx << " " << ny << " " << nnx << " " << nny << "\n";
if (!v[nnx][nny]) {
v[nnx][nny] = true;
pq.push({ nnx, nny, nt });
}
break;
}
if (lst[nx][ny] == -1) {
int nnx = nx - dx[i], nny = ny - dy[i];
if (!v[nnx][nny]) {
v[nnx][nny] = true;
pq.push({ nnx, nny, nt });
}
break;
}
if (lst[nx][ny] == 7) {
if (!v[nx][ny]) {
v[nx][ny] = true;
pq.push({ nx, ny, nt });
}
break;
}
nx += dx[i];
ny += dy[i];
}
}
}
}
return -1;
}
int main() {
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 5; ++j)
cin >> lst[i][j];
int sx, sy; cin >> sx >> sy;
cout << bfs(sx, sy);
}
728x90
'알고리즘 공부 > C++' 카테고리의 다른 글
[P5] 백준 10090번 Counting Inversions C++ 세그먼트 트리 (0) | 2025.03.26 |
---|---|
[G5] 백준 19598번 최소 회의실 개수 C++ 정렬, 멀티셋, 그리디 알고리즘, 이분 탐색 (0) | 2025.03.25 |
[G3] 백준 26086번 어려운 스케줄링 C++ 오프라인 쿼리, 덱, 정렬 (0) | 2025.03.22 |
[G1] 백준 1884번 고속도로 C++ 다익스트라 (0) | 2025.03.21 |
[G2] 백준 15559번 내 선물을 받아줘 C++ 깊이 우선 탐색 (0) | 2025.03.20 |