반응형
리뷰
https://www.acmicpc.net/problem/1584
0, 0에서 500, 500까지 생명이 최소로 깎인 상태로 이동하는 문제
다익스트라로 구현할까 했지만 그냥 기저 조건에 도달하면 바로 리턴하는게 좋을 것 같아 bfs를 돌렸다.
전역 변수
- n : 위험 구역의 개수를 저장할 변수
- m : 죽음 구역의 개수를 저장할 변수
- lst : 맵 정보를 저장할 정수형 2차 배열
- v : 방문 정보를 저장할 논리형 2차 배열
- dx, dy : 4방향 탐색을 하기 위한 방향 배열
함수
1. bfs
int bfs()
너비 우선 탐색을 사용해 시작 위치부터 목표 위치까지 생명을 가장 조금 사용하여 도착하는 경우를 구하는 함수
- Pos타입의 우선순위 큐 q를 초기화 해주고, 초기값 0, 0, 0을 넣어준다.
- v배열에 시작 좌표인 0, 0에 방문처리 후 q가 빌 때 까지 while루프를 수행해 준다.
- 매 루프마다 요소를 한개씩 뽑아주며 위치와 소요 시간을 정수형 변수 cx, cy, ct로 파싱해 준다.
- 기저 조건으로 만약 cx, cy가 둘다 500이라면 현재까지의 소요시간 ct를 리턴해 준다.
- 4방향 탐색을 진행하며 맵의 범위 안에 있고, 맵 상에서 -1이 아니며 방문하지 않은 경우 이동을 진행해 준다.
- 이동한 위치에 방문처리 후 맵 상에서 값이 1이면 시간을 늘려서, 아니면 시간을 그대로 q에 push해준다.
- while루프가 종료될 때 까지 기저조건에 도달하지 못했다면 -1을 리턴해 준다.
문제풀이
- n값을 입력 받고, n개의 위험 구역을 입력 받아 해당 구역의 넓이만큼 맵에 1로 저장해 준다.
- m값을 입력 받고, m개의 위험 구역을 입력 받아 해당 구역의 넓이만큼 맵에 -1로 저장해 준다.
- bfs함수를 호출하고 받은 리턴값을 출력해 준다.
트러블 슈팅
- 로직을 완벽하게 짰는데 예제의 출력값이 정확하게 나오지 않았다.
- x1 < x2, y1 < y2가 보장되지 않는 문제였다. 따라서 x1 > x2, y1 > y2일 경우 swap으로 두 값을 변경해 주었다.
참고 사항
- 가중치가 0 혹은 1인 경우만 있기에 다익스트라 보다 기저 조건에 도달하면 중간에 리턴하도록 로직을 짰다.
- 마찬가지로 0 혹은 1인 경우가 있기에 우선순위 큐를 통해 생명령을 가장 적게 잃은 경우를 우선 탐색 시켰다.
정답 코드
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
int n, m;
int lst[501][501];
bool v[501][501];
int dx[] = { 1, 0, 0, -1 };
int dy[] = { 0, 1, -1, 0 };
struct Pos {
int x, y, t;
bool operator<(const Pos& other) const {
return t > other.t;
}
};
int bfs() {
priority_queue<Pos> q;
q.push({ 0, 0, 0 });
v[0][0] = true;
while (!q.empty()) {
Pos pos = q.top(); q.pop();
int cx = pos.x, cy = pos.y, ct = pos.t;
if (cx == 500 && cy == 500) return ct;
for (int i = 0; i < 4; ++i) {
int nx = cx + dx[i], ny = cy + dy[i];
if (0 <= nx && nx < 501 && 0 <= ny && ny < 501 && lst[nx][ny] != -1 && !v[nx][ny]) {
v[nx][ny] = true;
if (lst[nx][ny]) q.push({ nx, ny, ct + 1 });
else q.push({ nx, ny, ct });
}
}
}
return -1;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
while (n--) {
int x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2;
if (x1 > x2) swap(x1, x2);
if (y1 > y2) swap(y1, y2);
for (int i = x1; i <= x2; ++i)
for (int j = y1; j <= y2; ++j)
lst[i][j] = 1;
}
cin >> m;
while (m--) {
int x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2;
if (x1 > x2) swap(x1, x2);
if (y1 > y2) swap(y1, y2);
for (int i = x1; i <= x2; ++i)
for (int j = y1; j <= y2; ++j)
lst[i][j] = -1;
}
cout << bfs();
}
728x90
반응형
'알고리즘 공부 > C++' 카테고리의 다른 글
[P4] 백준 12899번 데이터 구조 C++ 세그먼트 트리 (0) | 2025.01.26 |
---|---|
[G5] 백준 14567번 선수과목 (Prerequisite) C++ 위상 정렬 (0) | 2025.01.25 |
[G2] 백준 1365번 꼬인 전깃줄 C++ 이분 탐색, LIS (0) | 2025.01.23 |
[G1] 백준 13459번 구슬 탈출 C++ 구현, 시뮬레이션, 너비 우선 탐색 (0) | 2025.01.23 |
[G1] 백준 17143번 낚시왕 C++ 구현, 시뮬레이션, 우선순위 큐 (0) | 2025.01.22 |