19238 스타트택시 > 2036KB, 584ms
메모리는 보통, 속도는 느린편 -> 사람 찾을 때 BFS 한 번만 하면 됨!
- 간단한 로직
- BFS 기본
- 태울 사람이 남아있는지 체크하고 -> 고르고 -> 태우고
- 태울 사람이 남아있는지 체크 : 태운 사람을 move_people로 저장하고 태울때마다 move_people++, move_people이 M(승객 수)와 같아지면 종료
- 고르고 : queue에 담아둔 사람을 한명씩 bfs로 거리 체크함. 이때 태울 사람은 있지만 태우러 갈 수 없는 경우(사방이 벽)에는 flag를 써서 확인. 사람을 고르면 move_people++해주고 차량이동 및 연료 감소시킴
- 태우고 : 고른 사람의 출발지와 목적지만 bfs하고 차량 옮기고 연료 빼주고 연료 남아있으면 연료 충전
- 주의 사항
- 0차 : 종료 조건 고려안하고 로직 짬, 1차 : 연료만 고려하고 사람 고려 안함, 2차 : 모든 손님 이동 불가 고려 안함,
- 4차 : 택시와 손님이 같은 곳에 서있을 때 고려 안함
- y & x 주의하기!
#include <iostream>
#include <queue>
#define MAX 20
using namespace std;
typedef struct people {
bool finish = false;
int start_y;
int start_x;
int dest_y;
int dest_x;
}PEOPLE;
typedef struct bfs_struct {
int y, x, route = 0;
}BFS_STRUCT;
int N, M, map[MAX + 1][MAX + 1] = {};
long long int fuel;
int car_y, car_x;
PEOPLE pe_arr[MAX * MAX] = {};
int move_people = 0;
void input() {
cin >> N >> M >> fuel;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
cin >> map[i][j];
cin >> car_y >> car_x;
for (int i = 0; i < M; i++)
cin >> pe_arr[i].start_y >> pe_arr[i].start_x >> pe_arr[i].dest_y >> pe_arr[i].dest_x;
}
int go_y, go_x, pe_index, shortest_route;
int BFS(int index, bool mode) { // mode false : start, true : dest;
bool flag = false;
int goal_y, goal_x;
int result = 1000000;
bool visited[MAX + 1][MAX + 1] = {};
int dy[4] = { -1,1,0,0 }, dx[4] = { 0,0,-1,1 };
if (!mode) {
goal_y = pe_arr[index].start_y;
goal_x = pe_arr[index].start_x;
}
else {
goal_y = pe_arr[index].dest_y;
goal_x = pe_arr[index].dest_x;
}
queue<BFS_STRUCT> q;
q.push({ car_y, car_x, 0 });
visited[car_y][car_x] = true;
if (car_y == goal_y && car_x == goal_x) return 0;
while (!q.empty()) {
int now_y = q.front().y, now_x = q.front().x, now_route = q.front().route; q.pop();
for (int i = 0; i < 4; i++) {
int new_y = now_y + dy[i], new_x = now_x + dx[i];
if (new_y > N || new_x > N || new_y <= 0 || new_x <= 0
|| visited[new_y][new_x] || map[new_y][new_x] == 1) continue;
if (new_y == goal_y && new_x == goal_x && result > now_route + 1) {
result = now_route + 1;
flag = true;
continue;
}
q.push({ new_y, new_x, now_route + 1 });
visited[new_y][new_x] = true;
}
}
if (!flag) return -1;
return result;
}
bool choose() {
shortest_route = 1000000;
bool flag = false;
for (int i = 0; i < M; i++) {
if (pe_arr[i].finish) continue;
int bfs_result = BFS(i, false);
if (bfs_result < 0) continue;
flag = true;
if (bfs_result < shortest_route) {
pe_index = i; go_y = pe_arr[i].start_y; go_x = pe_arr[i].start_x; shortest_route = bfs_result;
}
else if (bfs_result == shortest_route) {
if (pe_arr[i].start_y < go_y) {
pe_index = i; go_y = pe_arr[i].start_y; go_x = pe_arr[i].start_x; shortest_route = bfs_result;
} else if (pe_arr[i].start_y == go_y) {
if (pe_arr[i].start_x < go_x) {
pe_index = i; go_y = pe_arr[i].start_y; go_x = pe_arr[i].start_x; shortest_route = bfs_result;
}
}
}
}
if (!flag) return false;
move_people++;
car_y = go_y;
car_x = go_x;
fuel -= shortest_route;
pe_arr[pe_index].finish = true;
if (fuel < 0) return false;
return true;
}
bool go() {
int bfs_result = BFS(pe_index, true);
if (bfs_result < 0) return false;
car_y = pe_arr[pe_index].dest_y;
car_x = pe_arr[pe_index].dest_x;
fuel -= bfs_result;
if (fuel >= 0) fuel += (bfs_result * 2);
else return false;
return true;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
input();
while (move_people < M) {
if (!choose()) {
cout << -1;
return 0;
}
if (!go()) {
cout << -1;
return 0;
}
}
cout << fuel;
return 0;
}
'coding > baekjoon_codingstudy' 카테고리의 다른 글
12100 2048(Easy) (0) | 2022.10.03 |
---|---|
21609 상어중학교 (0) | 2022.10.02 |
13460 구슬 탈출2 (0) | 2022.10.02 |
14891 톱니바퀴 (골드 5) (0) | 2021.10.05 |
18239 편안한 수열 만들기 (골드 3) (0) | 2021.08.19 |