-
백준 - 스타트 택시 (19238) [C++]문제 풀이/백준 2023. 9. 24. 17:40반응형
이 문제는 bfs를 이용해서 풀었다. 이 문제에서 핵심은 택시가 손님들을 찾는 과정에서 최단거리이며, 만약 거리가 같은 경우 행 번호가 작은, 행 번호도 같다면 열 번호가 작은 손님을 찾는 것이다. 이를 위해 처음에는 bfs의 상하좌우 탐색 순서를 상좌우하 순서로 탐색하고 찾은 경우를 리턴했지만, 이는 정답이 나오지 않았다. 그래서 두 번째 방법으로 일단 bfs를 맵 전체에 대해 돌리고, 손님들의 startY, startX를 기준으로 오름차순 정렬한 배열에 대해 최단거리를 비교하며 손님을 뽑는 형식으로 바꿔 정답을 도출해낼 수 있었다. 이 부분만 잘 해결한다면 나머지는 쉽게 구현 가능한 문제였다.
#include <iostream> #include <vector> #include <queue> #include <utility> #include <algorithm> using namespace std; struct passenger { int startY; int startX; int endY; int endX; }; int N, M; long long fuel; int matrix[21][21]; int dy[] = { -1, 0, 0, 1 }; int dx[] = { 0, -1, 1, 0 }; vector<passenger> pass; vector<vector<int>> dist; bool inRange(int y, int x) { if (1 <= y && y <= N && 1 <= x && x <= N) { return true; } return false; } void findPassenger(int startY, int startX) { dist = vector<vector<int>>(N + 1, vector<int>(N + 1, 0)); queue<pair<int, int>> q; q.push({ startY, startX }); dist[startY][startX] = 1; while (!q.empty()) { pair<int, int> present = q.front(); q.pop(); for (int i = 0; i < 4; i++) { int ny = present.first + dy[i]; int nx = present.second + dx[i]; if (inRange(ny, nx) && dist[ny][nx] == 0 && matrix[ny][nx] != 1) { dist[ny][nx] = dist[present.first][present.second] + 1; q.push({ ny, nx }); } } } } int movePassenger(int startY, int startX, int endY, int endX) { vector<vector<int>> visited(N + 1, vector<int>(N + 1, 0)); queue<pair<int, int>> q; q.push({ startY, startX }); visited[startY][startX] = 1; while (!q.empty()) { pair<int, int> present = q.front(); q.pop(); if (present.first == endY && present.second == endX) { return visited[present.first][present.second] - 1; } for (int i = 0; i < 4; i++) { int ny = present.first + dy[i]; int nx = present.second + dx[i]; if (inRange(ny, nx) && visited[ny][nx] == 0 && matrix[ny][nx] != 1) { visited[ny][nx] = visited[present.first][present.second] + 1; q.push({ ny, nx }); } } } return -1; } bool compare(passenger &a, passenger &b) { if (a.startY == b.startY) { return a.startX < b.startX; } return a.startY < b.startY; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> N >> M >> fuel; for (int y = 1; y <= N; y++) { for (int x = 1; x <= N; x++) { cin >> matrix[y][x]; } } int startY, startX; cin >> startY >> startX; for (int i = 1; i <= M; i++) { int sy, sx, ey, ex; cin >> sy >> sx >> ey >> ex; pass.push_back({ sy, sx, ey, ex }); } sort(pass.begin(), pass.end(), compare); for (int i = 0; i < M; i++) { // 1. move to passenger findPassenger(startY, startX); passenger result = { -1, -1, -1, -1 }; int index = -1; int tempDist = 1000000; for (int i = 0; i < pass.size(); i++) { passenger temp = pass[i]; int distance = dist[temp.startY][temp.startX]; if (distance > 0) { if (tempDist > distance) { tempDist = distance; result = temp; index = i; } } } tempDist--; if (index == -1) { cout << -1 << '\n'; return 0; } pass.erase(pass.begin() + index); if (fuel - tempDist < 0) { cout << -1 << '\n'; return 0; } fuel -= tempDist; startY = result.startY; startX = result.startX; int endY = result.endY; int endX = result.endX; // 2. move to destination tempDist = movePassenger(startY, startX, endY, endX); if (tempDist == -1) { cout << -1 << '\n'; return 0; } if (fuel - tempDist < 0) { cout << -1 << '\n'; return 0; } fuel += tempDist; startY = endY; startX = endX; } cout << fuel << '\n'; return 0; }
반응형'문제 풀이 > 백준' 카테고리의 다른 글
백준 - 마법사 상어와 블리자드 (21611) [C++] (2) 2023.10.03 백준 - 상어 중학교 (21609) [C++] (1) 2023.09.25 백준 - 어른 상어 (19237) [C++] (0) 2023.09.18 백준 - 모노미노도미노 2 (20061) [C++] (0) 2023.09.17 백준 - 신입 사원 (1946) [C++] (0) 2023.08.17