본문 바로가기

BOJ

백준 1726 / 로봇


BFS 문제


그저 최단거리를 찾는 문제아닌,  방향 바꾸는 행위와 1,2,3칸 직진이 추가된 BFS 문제다.




check 배열과 최단거리를 담는 d 배열을 방향값까지 추가하여 3차원으로 선언 후.


직진하는 경우와 방향을 바꾸는 경우를 구현했다.



1. 직진하는 경우


3칸까지 갈 수 있기떄문에


자신의 방향 앞에 놓인 값들이 모두 0일떄 직진할 수 있게 구현했다.



2. 방향을 바꾸는 경우


젤 헷갈렸던 부분


동쪽이 1 서쪽 2 남쪽3 북쪽4 이기 떄문에


예를 들어, 동쪽에서 서쪽에서 바꾸는 경우 숫자는 1이 들지만 방향을 두 번(오른쪽,오른쪽) 바꾸어야되기떄문에 


이런 경우들을 체크하는 조건문을 걸어두었다.



dir + i == 7 || dir + i == 3



dir은 현재 방향, i는 바꾸고자 하는 방향. 


동에서 서로 바꾸는 경우 dir+i가 3, 남에서 북으로 바꾸는 경우 7이 되기 떄문에 방향을 두 번 바꾸었다고 하면 된다.




코드


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
#include<stdio.h>
#include<vector>
#include<queue>
#include<iostream>
#include<algorithm>
#include<memory.h>
#include<tuple>
#include<math.h>
 
using namespace std;
 
int dx[] = {00,0,1,-1 };
int dy[] = { 01,-1,0,0 };
 
 
int map[101][101];
bool check[101][101][5];
int d[101][101][5];
 
int n, m;
int sx, sy, sdir;
int gx, gy, gdir;
 
queue<tuple<intintint>>q;
 
bool gocheck(int x, int y, int nx, int ny) {
 
    
    if (nx >= 1 && ny >= 1 && nx <= n && ny <= m) {
        if (x < nx ) {
            for (int i = x; i <= nx; i++) {
                for (int j = y; j <= ny; j++) {
                    if (map[i][j] == 1) {
                        return false;
                    }
                }
            }
        }
        if (y < ny) {
            for (int i = x; i <= nx; i++) {
                for (int j = y; j <= ny; j++) {
                    if (map[i][j] == 1) {
                        return false;
                    }
                }
            }
        }
        if (x > nx) {
            for (int i = nx; i <= x; i++) {
                for (int j = y; j <= ny; j++) {
                    if (map[i][j] == 1) {
                        return false;
                    }
                }
            }
        }
        if (y > ny) {
            for (int i = x; i <= nx; i++) {
                for (int j = ny; j <= y; j++) {
                    if (map[i][j] == 1) {
                        return false;
                    }
                }
            }
        }
 
    }
    else {
        return false;
    }
    return true;
 
}
int main() {
    
    //freopen("Text.txt", "r", stdin);
    cin >> n >> m;
 
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> map[i][j];
        }
    }
 
    cin >> sx >> sy >> sdir;
    cin >> gx >> gy >> gdir;
 
    q.push(make_tuple(sx, sy, sdir));
    check[sx][sy][sdir] = true;
 
    while (!q.empty()) {
        int x, y, dir;
        tie(x, y, dir) = q.front();
        q.pop();
 
        for (int c = 1; c <= 2; c++) {
            if (c == 1) { // 직진
                for (int go = 1; go <= 3; go++) {
                    int nx = x + go * dx[dir];
                    int ny = y + go * dy[dir];
 
    
                    if (nx >= 1 && ny >= 1 && nx <= n && ny <= m) {
                        if (map[nx][ny] == 0 && check[nx][ny][dir] == false && gocheck(x, y, nx, ny)==true) {
                            check[nx][ny][dir] = true;
                            d[nx][ny][dir] = d[x][y][dir] + 1;
                            q.push(make_tuple(nx, ny, dir));
                        }
 
                    }
                }
            }
            if (c == 2) { // 방향 바꾸기
                for (int i = 1; i <= 4; i++) {
                    if (i == dir) continue;
 
                    if (check[x][y][i] == false) {
 
                        if (dir + i == 7 || dir + i == 3) {
                            check[x][y][i] = true;
                            d[x][y][i] = d[x][y][dir] + 2;
                            q.push(make_tuple(x, y, i));
                        }
                        else {
                            check[x][y][i] = true;
                            d[x][y][i] = d[x][y][dir] + 1;
                            q.push(make_tuple(x, y, i));
                        }
                    }
                }
            }
        }
    }
 
    cout << d[gx][gy][gdir] << endl;
}
 
cs


'BOJ' 카테고리의 다른 글

백준 9205 / 맥주 마시면서 걸어가기  (0) 2019.01.11
백준 11559 / Puyo Puyo  (0) 2019.01.11
백준 9372 / 상근이의 여행  (0) 2019.01.09
백준 1939 / 중량제한  (0) 2019.01.09
백준 5427 / 불  (0) 2019.01.08