백준문제풀이/구현

19238번-스타트택시

반응형

문제

https://www.acmicpc.net/problem/19238

 

19238번: 스타트 택시

첫 줄에 N, M, 그리고 초기 연료의 양이 주어진다. (2 ≤ N ≤ 20, 1 ≤ M ≤ N2, 1 ≤ 초기 연료 ≤ 500,000) 연료는 무한히 많이 담을 수 있기 때문에, 초기 연료의 양을 넘어서 충전될 수도 있다. 다

www.acmicpc.net


접근방법

1) 접근 사고

1. 내가 태울 승객을 BFS 탐색으로 정한다, 이때 소모한 가스값은 갱신해준다.

2. 태울 승객의 위치에서 도착지까지 BFS 탐색을 한다, 이때 소모한 가스값은 갱신해준다.

 

2) 시간 복잡도

O(V + E)

 

3) 배운 점

여러 번 시도한 문제이다. 테스트 케이스는 다 통과하나 문제가 자꾸 틀렸습니다가 나와서 힘들었다 이에 대해서 안 좋은 습관을 찾았고 글을 따로 작성했다.

https://hyeophyeop.tistory.com/106

 

BFS, DFS 탐색 팁

저는 항상 BFS 문제를 풀 때 구현을 다한 뒤 테스트케이스를 다 통과하고 맞왜틀을 정말 많이 겪었습니다. 한 번 갇힌 사고에서는 탈출하기 정말 어려운게 알고리즘 문제이고 이러한 경우를 어떻

hyeophyeop.tistory.com

안 좋은 습관을 가지고 있어서 나중에 똑같은 실수를 저지를까 봐 따로 정리했다.

 

4) PS

디버깅 그만 하고 싶다...


정답 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include <bits/stdc++.h>
 
using namespace std;
const int MAX = 21;
int my[] = {-1,0,1,0};
int mx[] = {0,-1,0,1};
 
struct Car{
    int y, x, gas;
};
 
bool operator < (const Car &a, const Car &b){
    if(a.gas != b.gas){
        return a.gas < b.gas;
    }
    if(a.y != b.y){
        return a.y > b.y;
    }
    if(a.x != b.x){
        return a.x > b.x;
    }
    return false;
}
 
struct drive{
    int n, m, k;
    int board[MAX][MAX];
    Car car;
    drive(int n, int m, int k) : n(n), m(m), k(k) {}
    tuple<int,int,int,int> cityzen[401];
    bool visited[MAX][MAX];
    int fNum;
 
    bool isValid(int y, int x){
        return (y >= 0 && y < n && x >= 0 && x < n);
    }
 
    void init(){
        for(int i = 0; i < n ; i++){
            for(int j = 0; j < n; j++){
                cin >> board[i][j];
                if(board[i][j] == 1)
                    board[i][j] = -1;
            }
        }
        cin >> car.y >> car.x;
        car.gas = k;
        car.y--, car.x--;
        for(int i = 1; i <= m; i++){
            int sy, sx, ey, ex;
            cin >> sy >> sx >> ey >> ex;
            sy--, sx--, ey--, ex--;
            board[sy][sx] = i;
            cityzen[i] = {sy, sx, ey, ex};
        }
    }
 
    bool find_BFS(){
        priority_queue<Car> pq;
        pq.push({car.y, car.x, car.gas});
        visited[car.y][car.x] = true;
        memset(visited, falsesizeof visited);
 
        int cnt = 0;
        while(!pq.empty()){
            int pqSize = pq.size();
 
            for(int i = 0; i < pqSize; i++){
                auto[y, x, gas] = pq.top();
                pq.pop();
 
                if(board[y][x] > 0){
                    if(gas >= 0){
                        car.y = y;
                        car.x = x;
                        car.gas = gas;
                        fNum = board[y][x];
                        return true;
                    }
                    else
                        return false;
                }
                for(int d = 0; d < 4; d++){
                    int ny = y + my[d];
                    int nx = x + mx[d];
                    if(isValid(ny, nx)){
                        if(!visited[ny][nx] && board[ny][nx] != -1){
                            pq.push({ny, nx, gas - 1});
                            visited[ny][nx] = true;
                        }
                    }
                }
            }
            cnt++;
        }
        return false;
    }
 
    bool goal_BFS(){
        memset(visited, falsesizeof visited);
        queue<pair<int,int>> q;
        q.push({car.y, car.x});
        visited[car.y][car.x] = true;
        auto[sy, sx, ey, ex] = cityzen[fNum];
        int cnt = 0;
 
        while(!q.empty()){
            int qSize = q.size();
            for(int i =  0; i < qSize; i++){
                auto[y, x] = q.front();
                q.pop();
                if(y == ey && x == ex){
                    car.gas -= cnt;
                    if(car.gas >= 0){
                        car.gas += cnt * 2;
                        car.y = ey;
                        car.x = ex;
                        board[sy][sx] = 0;
                        return true;
                    } else{
                        return false;
                    }
                }
                for(int d = 0; d < 4; d++){
                    int ny = y + my[d];
                    int nx = x + mx[d];
                    if(isValid(ny, nx)){
                        if(!visited[ny][nx] && board[ny][nx] != -1){
                            q.push({ny, nx});
                            visited[ny][nx] = true;
                        }
                    }
                }
            }
            cnt++;
        }
        return false;
    }
 
    void printBoard(){
        for(int i = 0 ; i < n; i++){
            for(int j = 0; j < n; j++){
                cout << board[i][j] <<" ";
            }
            cout <<"\n";
        }
        cout <<"========board========" <<"\n";
    }
};
 
int main(){
    int n, m, k;
    cin >> n >> m >> k;
    drive op(n,m,k);
    op.init();
    //op.printBoard();
    for(int i = 0; i < m; i++){
        if(!op.find_BFS()){
            cout << "-1" <<"\n";
            return 0;
        }
        if(!op.goal_BFS()){
            cout << "-1" <<"\n";
            return 0;
        }
    }
    cout << op.car.gas << "\n";
}
cs
반응형

'백준문제풀이 > 구현' 카테고리의 다른 글

20057번 - 마법사 상어와 토네이토  (0) 2021.09.26
20055번-컨베이어 벨트 위의 로봇  (0) 2021.09.25
19237번-어른 상어  (0) 2021.09.24
19236번-청소년상어  (0) 2021.09.22
17779번-게리멘더링2  (0) 2021.09.16