코딩 공부/백준

[백준][C++] 17836 공주님을 구해라!

김 정 환 2021. 3. 23. 18:56
반응형

www.acmicpc.net/problem/17836

 

17836번: 공주님을 구해라!

용사는 마왕이 숨겨놓은 공주님을 구하기 위해 (N, M) 크기의 성 입구 (1,1)으로 들어왔다. 마왕은 용사가 공주를 찾지 못하도록 성의 여러 군데 마법 벽을 세워놓았다. 용사는 현재의 가지고 있는

www.acmicpc.net

 

 

 

알고리즘 종류

    - BFS

 

 

 

사고 과정

    - 경우는 2가지이다. 

        1. 검 없이 공주님에게 달려간다. (1, 1)에서 시작해서 (n, m)에 도착하는 BFS.

        2. 검을 찾고 공주님에게 달려간다. (1, 1)에서 (sword_y, sword_x) 검이 있는 곳에 갔다가 (n, m)에 도착하는 BFS

 

    - 두 가지 경우에서 나온 시간 중에 최소 값이 제한된 시간 이하인지 확인해서 결과를 출력한다.

 

 

 

구현(C++)

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
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#define MAX 987654321;
 
using namespace std;
 
int n, m, t;
int sword_y, sword_x;
 
int mat[101][101];
int isVisited[101][101];
int dir[4][2= {{1,0}, {0,1}, {-1,0}, {0,-1}};
 
 
bool isValid(int y, int x){
    return (y>=1 && y<=n) && (x>=1 && x<=m);
}
 
 
int bfs(int sy, int sx, int ey, int ex, bool hasSword){
    memset(isVisited, 0sizeof(isVisited));
    queue<pair<intint> > q;
    q.push({sy, sx});
    isVisited[sy][sx] = 1;
    
    int time = 0;
    while(!q.empty()){
        
        int size = q.size();
        while(size--){
            
            int cy = q.front().first;
            int cx = q.front().second;
            q.pop();
            
            if(cy==ey && cx==ex) return time;
            
            for(int d=0; d<4; d++){
                int ny = cy + dir[d][0];
                int nx = cx + dir[d][1];
                
                if(isVisited[ny][nx]) continue;
                if(!isValid(ny, nx)) continue;
                // 검이 있으면 그냥 뚫고 가고, 검이 없으면 벽을 검사한다. 
                if(!hasSword)
                    if(mat[ny][nx] == 1continue;
 
                isVisited[ny][nx] = 1;
                q.push({ny, nx});
            }
        }
        
        time++;
    }
    
    return MAX; 
}
 
 
int main(void){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    
    cin >> n >> m >> t;
    
    for(int i=1; i<=n; i++){
        for(int j=1; j<=m; j++){
            cin >> mat[i][j];
            if(mat[i][j] == 2) {
                sword_y = i;
                sword_x = j;
            }
        }
    }
    
    // 검 없이 구하자
    int timeNoSword = bfs(11, n, m, false);
    // 검 가지고 구하자
    int timeWithSword = bfs(11, sword_y, sword_x, false);
    timeWithSword += bfs(sword_y, sword_x, n, m, true);
    
    int shortTime = min(timeNoSword, timeWithSword);
    
    if(shortTime > t) cout << "Fail" << endl;
    else cout << shortTime;
}
 
cs

 

 

 

시행착오

    - 함수 1개에 bool 자료형으로 켰다가 끄는 조건을 한 번 추가해 보았다.

반응형

'코딩 공부 > 백준' 카테고리의 다른 글

[백준][C++] 2234 성곽  (0) 2021.03.24
[백준][C++] 5427 불  (0) 2021.03.23
[백준][C++] 2024 선분 덮기  (0) 2021.03.23
[백준][C++] 18809 gaaaaaaaaaarden  (0) 2021.03.20
[백준][C++] 10217 KCM Travel  (0) 2021.03.19