리뷰
https://www.acmicpc.net/problem/2194
2차원 맵에서 출발지에서 도착지까지 사각형이 이동하는 최단 시간을 구하는 문제
전역 변수
- n, m : 맵의 세로/가로 길이를 저장할 변수
- a, b : 사각형의 세로/가로 길이를 저장할 변수
- k : 장애물의 개수를 저장할 변수
- lst : 장애물의 위치를 표기하기 위한 배열
- v : 방문 여부를 확인하기 위한 배열
- dx, dy : 4방향 탐색을 위한 방향 배열
- Pos : 현재 위치와 소요 시간을 정의하기 위한 구조체
함수
1. bfs
int bfs(int sx, int sy, int ex, int ey) {
queue<Pos> q;
q.push({ sx, sy, 0 });
v[sx][sy] = true;
while (!q.empty()) {
Pos pos = q.front(); q.pop();
int cx = pos.x, cy = pos.y, ct = pos.t;
if (cx == ex && cy == ey) 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 + a - 1 <= n && 0 < ny && ny + b - 1 <= m && !v[nx][ny]) {
v[nx][ny] = true;
bool move = true;
if (i == 0) {
for (int j = 0; j < b; ++j) {
if (lst[nx + a - 1][ny + j]) {
move = false;
break;
}
}
}
else if (i == 1) {
for (int j = 0; j < b; ++j) {
if (lst[nx][ny + j]) {
move = false;
break;
}
}
}
else if (i == 2) {
for (int j = 0; j < a; ++j) {
if (lst[nx + j][ny + b - 1]) {
move = false;
break;
}
}
}
else {
for (int j = 0; j < a; ++j) {
if (lst[nx + j][ny]) {
move = false;
break;
}
}
}
if (move) {
q.push({ nx, ny, nt });
}
}
}
}
return -1;
}
장애물이 없는 경로에서 사각형의 이동 가능 여부와 출발지부터 목적지까지 도달하기 까지의 소요 시간을 구하는 함수
문제풀이
- 전역 변수 n, m, a, b, k에 값을 입력 받고, k개의 장애물의 좌표를 입력받아 lst배열에 표시해 준다.
- 변수 sx, sy, ex, ey에 출발 좌표와 목표 좌표를 입력 받고, bfs함수에 매개변수로 전달하여 호출한다.
- Pos타입의 큐 q를 초기화 하고, 초기 위치 sx, sy와 소요시간 0을 push해준다.
- v배열에 시작 위치의 좌표를 방문처리해준다.
- q가 빌때까지 while루프를 수행하고, 매 루프마다 요소를 한개씩 꺼내어 준다.
- 기저 조건으로 현재 위치가 도착 위치인 ex, ey에 도달한 경우 ct를 리턴해 준다.
- 4방향 탐색을 시작하고, 사각형이 맵의 범위를 벗어나지 않으면서 방문하지 않았다면 이동을 진행한다.
- 방문처리를 진행해 주고, 변수 move를 true로 초기화 시켜준다.
- 각 이동 방향에 따라 이동한 면의 가장자리에 장애물이 없다면 q에 새로운 위치와 시간을 push해준다.
- while루프가 종료될 때까지 기저조건에 도달하지 못했다면 -1을 리턴해준다.
- bfs함수의 리턴값을 출력해 준다.
트러블 슈팅
- 범위 체크를 할때 사각형의 우측 상단 꼭지점만 체크해 주어 Fail을 받았다.
- 사각형의 모든 면이 범위 내에 존재하는지 체크해주어 문제를 해결하였다.
- 상하 이동 시 이동한 행의 열을, 좌우 이동 시 이동한 열의 행을 체크해 주었으나 각각 왼쪽, 위쪽만 해주어 Fail을 받았다.
- 상하좌우 이동 시 각각 위쪽, 아래쪽, 왼쪽, 오른쪽 면을 확인해 주어 AC를 받았다.
참고 사항
없음
정답 코드
#include<iostream>
#include<queue>
using namespace std;
int n, m, a, b, k;
bool lst[501][501];
bool v[501][501];
int dx[] = { 1, -1, 0, 0 };
int dy[] = { 0, 0, 1, -1 };
struct Pos {
int x, y, t;
};
int bfs(int sx, int sy, int ex, int ey) {
queue<Pos> q;
q.push({ sx, sy, 0 });
v[sx][sy] = true;
while (!q.empty()) {
Pos pos = q.front(); q.pop();
int cx = pos.x, cy = pos.y, ct = pos.t;
if (cx == ex && cy == ey) 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 + a - 1 <= n && 0 < ny && ny + b - 1 <= m && !v[nx][ny]) {
v[nx][ny] = true;
bool move = true;
if (i == 0) {
for (int j = 0; j < b; ++j) {
if (lst[nx + a - 1][ny + j]) {
move = false;
break;
}
}
}
else if (i == 1) {
for (int j = 0; j < b; ++j) {
if (lst[nx][ny + j]) {
move = false;
break;
}
}
}
else if (i == 2) {
for (int j = 0; j < a; ++j) {
if (lst[nx + j][ny + b - 1]) {
move = false;
break;
}
}
}
else {
for (int j = 0; j < a; ++j) {
if (lst[nx + j][ny]) {
move = false;
break;
}
}
}
if (move) {
q.push({ nx, ny, nt });
}
}
}
}
return -1;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m >> a >> b >> k;
while (k--) {
int x, y; cin >> x >> y;
lst[x][y] = true;
}
int sx, sy, ex, ey;
cin >> sx >> sy >> ex >> ey;
cout << bfs(sx, sy, ex, ey);
}
728x90
'알고리즘 공부 > C++' 카테고리의 다른 글
[G3] 백준 23563번 벽 타기 C++ 다익스트라 (0) | 2025.04.20 |
---|---|
[G2] 백준 16227번 의약품 수송 C++ 다익스트라 (1) | 2025.04.19 |
[G4] 백준 2412번 암벽 등반 C++ 너비 우선 탐색, 해시맵 (0) | 2025.04.15 |
[G4] 백준 22116번 창영이와 퇴근 C++ 다익스트라 (0) | 2025.04.14 |
[G2] 백준 1486번 등산 C++ 다익스트라, 정렬 (0) | 2025.04.13 |