13460 째로탈출 2


깔끔한 코드는 도저히 생각이 나지 않아서 경우의 수들에 대해 하드코딩 했다......

가장 중요한 아이디어는 rx, ry, bx, by를 매개변수로 받아 지점에 대한 타당성을 검증하는 것인거 같다. 



1. 직전에 상하로 움직였으면 이번엔 좌우만 움직여보고, 직전에 좌우로 움직였으면 상하로만 움직인다.


2. 파란공을 먼저 움직여보고 타당하면 빨간공을 움직인다.


3. 빨간공까지 움직였을때 빨간공과 파란공의 위치가 같은경우 인자로 받아왔던 rx,ry,bx,by 값을 비교해 둘중 하나를 한칸 옮겨준다.


4. cnt가 10이하인 모든 방법을 탐색한다.




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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#include <iostream>
#include <algorithm>
#include <string>
#define INF 20
using namespace std;
 
int n, m, rx, ry, bx, by, res;
int map[10][10];
 
void dfs(int rx,int ry,int bx,int by,int dir,int cnt) {
    if (cnt == 11return;
 
    bool next_flag = false;
 
    int rrx = rx;
    int rry = ry;
    int bbx = bx;
    int bby = by;
 
    //직전칸에서 좌우로 움직인 경우
    if (dir == 1) {
        //위 방향
        for (int i = bbx - 1; i >=0; i--) {
            if (map[i][bby] == 'O') {
                break;
            }
            if (map[i][bby] == '#') {
                bbx = i + 1;
                next_flag = true;
                break;
            }
        }
        if (next_flag) {
            for (int i = rrx - 1; i >= 0; i--) {
                if (map[i][rry] == 'O') {
                    res = min(res, cnt);
                    break;
                }
                if (map[i][rry] == '#') {
                    rrx = i + 1;
                    if (rrx == bbx && ry==by) {
                        if (rx > bx) rrx += 1;
                        else bbx += 1;
                    }
                    dfs(rrx, rry, bbx, bby, 2, cnt + 1);
                    break;
                }
            }
        }
        //아래 방향
        next_flag = false;
        rrx = rx;
        rry = ry;
        bbx = bx;
        bby = by;
        for (int i = bbx + 1; i < n; i++) {
            if (map[i][bby] == 'O') {
                break;
            }
            if (map[i][bby] == '#') {
                bbx = i - 1;
                next_flag = true;
                break;
            }
        }
        if (next_flag) {
            for (int i = rrx + 1; i < n; i++) {
                if (map[i][rry] == 'O') {
                    res = min(res, cnt);
                    break;
                }
                if (map[i][rry] == '#') {
                    rrx = i - 1;
 
                    if (rrx == bbx && ry == by) {
                        if (rx > bx) bbx -= 1;
                        else rrx -= 1;
                    }
                    dfs(rrx, rry, bbx, bby, 2, cnt + 1);
                    break;
                }
            }
        }
 
    }
    //직전칸에서 상하로 움직인 경우
    else if (dir == 2) {
        next_flag = false;
        rrx = rx;
        rry = ry;
        bbx = bx;
        bby = by;
 
        //왼쪽 방향
        for (int i = bby - 1; i >= 0; i--) {
            if (map[bbx][i] == 'O') {
                break;
            }
            if (map[bbx][i] == '#') {
                bby = i + 1;
                next_flag = true;
                break;
            }
        }
        if (next_flag) {
            for (int i = rry - 1; i >= 0; i--) {
                if (map[rrx][i] == 'O') {
                    res = min(res, cnt);
                    break;
                }
                if (map[rrx][i] == '#') {
                    rry = i + 1;
                    if (rx == bx && rry == bby) {
                        if (ry > by) rry += 1;
                        else bby += 1;
                    }
                    dfs(rrx, rry, bbx, bby, 1, cnt + 1);
                    break;
                }
            }
        }
 
        next_flag = false;
        rrx = rx;
        rry = ry;
        bbx = bx;
        bby = by;
 
        //오른쪽 방향
        for (int i = bby + 1; i < m; i++) {
            if (map[bbx][i] == 'O') {
                break;
            }
            if (map[bbx][i] == '#') {
                bby = i - 1;
                next_flag = true;
                break;
            }
        }
        if (next_flag) {
            for (int i = rry + 1; i < m; i++) {
                if (map[rrx][i] == 'O') {
                    res = min(res, cnt);
                    break;
                }
                if (map[rrx][i] == '#') {
                    rry = i - 1;
                    if (rx == bx && rry == bby) {
                        if (ry > by) bby -= 1;
                        else rry -= 1;
                    }
                    dfs(rrx, rry, bbx, bby, 1, cnt + 1);
                    break;
                }
            }
        }
    }
}
 
int main() {
    ios_base::sync_with_stdio(false);
 
    cin >> n >> m;
 
    for (int i = 0; i < n; i++) {
        string buf;
        cin >> buf;
        for (int j = 0; j < m; j++) {
            map[i][j] = buf[j];
            if (map[i][j] == 'R') {
                rx = i;
                ry = j;
            }
            if (map[i][j] == 'B') {
                bx = i;
                by = j;
            }
        }
    }
 
    res = INF;
    dfs(rx, ry, bx, by, 11);
    dfs(rx, ry, bx, by, 21);
 
    if (res == INF) cout << -1 << endl;
    else cout << res << endl;
    return 0;
}
cs


'BOJ::문제풀이' 카테고리의 다른 글

12851 숨바꼭질 2  (0) 2018.03.26
1600 말이 되고픈 원숭이  (0) 2018.03.26
14500 테트로미노  (0) 2018.03.25
4179 불!  (0) 2018.03.25
5558 치 ~ 즈  (0) 2018.03.24

+ Recent posts