백준의 구슬탈출4(15653) 문제이다.

[ 문제 바로가기 ]


[ 문제풀이 ]

1) 구슬탈출 시리즈의 4번째, 구슬탈출4 문제이다. 이전의 구슬탈출 시리즈들(1, 2, 3)은 모두 DFS로 풀어보았지만,

   이 문제는 DFS로 탐색할 경우 본인의 코드는 재귀에서 빠져 나오지 못하는 문제점이 있어서 BFS로 풀어보았다.

   하지만, 탐색하는 그 중간 과정은 DFS와 동일하고, 본인이 풀었던 이전 시리즈들의 로직과 똑같기 때문에

   이 로직을 이 글에서는 설명하지 않겠다.

   [ 구슬탈출2 풀이 바로가기(로직 설명) ]

   BFS에 사용되는 Queue에서 관리하는 변수는 총 5개를 사용하였다.

   { 빨간공 x좌표 , 빨간공 y좌표 , 파란공 x좌표 , 파란공 y좌표 , 움직인횟수 }

   이렇게 5개를 관리해 주었다.

   위에서 말했듯이 BFS에서 탐색을 하는 과정은 이전 시리즈들의 로직과 똑같은 방법으로 탐색을 진행해 주었고

   BFS에서 가장 중요한 방문 체크는 4차원배열 Visit[][][][] 를 만들어서 관리해주었다.

   4차원 배열로 만든 이유는, Visit[Red_x][Red_y][Blue_x][Blue_y] 이런식으로 빨간공과 파란공이 움직이는 좌표를

   함께 관리해주기 위함이다. 빨간공만 관리할 경우, 방문 처리가 제대로 되지 않을 수 있기 때문에 빨간공 파랑공의

   좌표를 함께 관리하기 위해서 4차원으로 만들어 주었다.


[ 소스코드 ]

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
#include<iostream>
#include<string>
#include<cmath>
#include<queue>
 
#define endl "\n"
#define MAX 10
#define INF 987654321
using namespace std;
 
int N, M, Answer = INF;
string Answer_Str;
char MAP[MAX][MAX];
bool Visit[MAX][MAX][MAX][MAX];
pair<intint> Red, Blue;
 
int dx[] = { 001-1 };
int dy[] = { 1-100 };
 
struct INFO
{
    int Rx, Ry;
    int Bx, By;
    int Cnt;
};
 
int Min(int A, int B) { if (A < B) return A; return B; }
 
void Input()
{
    cin >> N >> M;
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < M; j++)
        {
            cin >> MAP[i][j];
            if (MAP[i][j] == 'R')
            {
                Red.first = i;
                Red.second = j;
                MAP[i][j] = '.';
            }
            else if (MAP[i][j] == 'B')
            {
                Blue.first = i;
                Blue.second = j;
                MAP[i][j] = '.';
            }
        }
    }
}
 
int Find_Distance(int x, int y, int xx, int yy)
{
    return abs(x - xx) + abs(y - yy);
}
 
void BFS()
{
    queue<INFO> Q;
    Q.push({ Red.first, Red.second, Blue.first, Blue.second, 0 });
    Visit[Red.first][Red.second][Blue.first][Blue.second] = true;
 
    while (Q.empty() == 0)
    {
        int Rx = Q.front().Rx;
        int Ry = Q.front().Ry;
        int Bx = Q.front().Bx;
        int By = Q.front().By;
        int Cnt = Q.front().Cnt;
        Q.pop();
 
        for (int i = 0; i < 4; i++)
        {
            bool RedFlag, BlueFlag;
            RedFlag = BlueFlag = false;
 
            int nRx = Rx + dx[i];
            int nRy = Ry + dy[i];
            int nBx = Bx + dx[i];
            int nBy = By + dy[i];
            int nCnt = Cnt + 1;
 
            while (1)
            {
                if (MAP[nRx][nRy] == '#'break;
                if (MAP[nRx][nRy] == 'O')
                {
                    RedFlag = true;
                    break;
                }
                nRx = nRx + dx[i];
                nRy = nRy + dy[i];
            }
            nRx = nRx - dx[i];
            nRy = nRy - dy[i];
 
            while (1)
            {
                if (MAP[nBx][nBy] == '#'break;
                if (MAP[nBx][nBy] == 'O')
                {
                    BlueFlag = true;
                    break;
                }
                nBx = nBx + dx[i];
                nBy = nBy + dy[i];
            }
            nBx = nBx - dx[i];
            nBy = nBy - dy[i];
 
            if (BlueFlag == truecontinue;
            if (RedFlag == true)
            {
                cout << nCnt << endl;
                return;
            }
 
            if (nRx == nBx && nRy == nBy)
            {
                int Red_Dist = Find_Distance(Rx, Ry, nRx, nRy);
                int Blue_Dist = Find_Distance(Bx, By, nBx, nBy);
                
                if (Red_Dist > Blue_Dist)
                {
                    nRx = nRx - dx[i];
                    nRy = nRy - dy[i];
                }
                else
                {
                    nBx = nBx - dx[i];
                    nBy = nBy - dy[i];
                }
            }            
            if (Visit[nRx][nRy][nBx][nBy] == truecontinue;
            Visit[nRx][nRy][nBx][nBy] = true;
            Q.push({ nRx, nRy, nBx, nBy, nCnt });            
        }
    }
    cout << -1 << endl;
}
 
void Solution()
{
    BFS();
}
 
void Solve()
{
    Input();
    Solution();
}
 
int main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
 
    //freopen("Input.txt", "r", stdin);
    Solve();
 
    return 0;
}
cs

'[ BOJ Code ] > # BOJ -' 카테고리의 다른 글

[ 백준 1026 ] 보물 (C++)  (2) 2020.02.19
[ 백준 15486 ] 퇴사2 (C++)  (2) 2020.02.19
[ 백준 15644 ] 구슬 탈출3 (C++)  (4) 2020.02.04
[ 백준 18160 ] 숫자 야구 (C++)  (0) 2020.01.31
[ 백준 1175 ] 배달 (C++)  (2) 2020.01.30

+ Recent posts