SWExpertAcademy의 오 ! 나의 여신님(7793 / D5) 문제이다.


[ 문제풀이 ]

현재 수연이가 위치한 곳에서, 악마의 손아귀 영역을 피해서 여신님께 갈 수 있는 최소시간을 구해야 하는 문제이다.

본인은 이 문제를 너비우선탐색(BFS) 방법을 이용해서 접근해보았는데, 총 2번의 BFS를 사용해 주었다.

첫 번째 BFS는 '악마들의 맵'을 생성하기 위해서 사용한 BFS이다.

초기에 악마가 존재하는 좌표들을 시작점으로, 모든 좌표에 악마의 손아귀가 퍼질 수 있는 최소시간을 구해서 저장하는

' 악마들의 맵'을 생성해주었다.

그 이후, 수연이를 BFS탐색을 통해서 여신님께 갈 수 있는지 판단해 주었다.

수연이의 BFS에서는 미리 만들어둔 악마들의 맵과 시간을 비교해가면서 이동하려는 좌표에 갈 수 있는지 없는지를

판단해주면서 구해주었다.


[ 소스코드 ]

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
#include<iostream>
#include<queue>
#include<vector>
#include<cstring>
#include<string>
 
#define endl "\n"
#define MAX 50
#define INF 987654321
using namespace std;
 
int N, M, Answer;
char MAP[MAX][MAX];
int Devil_MAP[MAX][MAX];
bool Visit[MAX][MAX];
vector<pair<intint>> Devil;
pair<intint> Start, End;
string GameOver = "GAME OVER";
 
int dx[] = { 001-1 };
int dy[] = { 1-100 };
 
void Initialize()
{
    memset(Visit, falsesizeof(Visit));
    Devil.clear();
    for (int i = 0; i < MAX; i++)
    {
        for(int j = 0 ; j < MAX; j++)
        { 
            Devil_MAP[i][j] = INF;
        }
    }
}
 
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] == 'S')
            {
                Start.first = i;
                Start.second = j;
            }
            else if (MAP[i][j] == 'D')
            {
                End.first = i;
                End.second = j;
            }
            else if (MAP[i][j] == '*') Devil.push_back(make_pair(i, j));
        }
    }
}
 
void Make_Devil_MAP()
{
    queue<pair<intint>> Q;
    for(int i = 0 ; i < Devil.size(); i++)
    { 
        int x = Devil[i].first;
        int y = Devil[i].second;
        Q.push(make_pair(x, y));
        Devil_MAP[x][y] = 0;        
    }
 
    while (Q.empty() == 0)
    {
        int x = Q.front().first;
        int y = Q.front().second;
        Q.pop();
 
        for (int i = 0; i < 4; i++)
        {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if (nx >= 0 && ny >= 0 && nx < N && ny < M)
            {
                if (MAP[nx][ny] == 'X'continue;
                if (MAP[nx][ny] == 'D'continue;
 
                if (Devil_MAP[nx][ny] > Devil_MAP[x][y] + 1)
                {
                    Devil_MAP[nx][ny] = Devil_MAP[x][y] + 1;
                    Q.push(make_pair(nx, ny));
                }
            }
        }
    }
}
 
int Move()
{
    queue<pair<pair<intint>int>> Q;
    Q.push(make_pair(make_pair(Start.first, Start.second), 0));
    Visit[Start.first][Start.second] = true;
 
    while (Q.empty() == 0)
    {
        int x = Q.front().first.first;
        int y = Q.front().first.second;
        int Cnt = Q.front().second;
        Q.pop();
 
        if (x == End.first && y == End.second) return Cnt;
 
        for (int i = 0; i < 4; i++)
        {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if (nx >= 0 && ny >= 0 && nx < N && ny < M)
            {
                if (MAP[nx][ny] == 'X'continue;
                if (Visit[nx][ny] == truecontinue;
 
                if (Devil_MAP[nx][ny] > Cnt + 1)
                {
                    Visit[nx][ny] = true;
                    Q.push(make_pair(make_pair(nx, ny), Cnt + 1));
                }
            }
        }
    }
    return -1;
}
 
void Solution()
{
    Make_Devil_MAP();
    Answer = Move();
}
 
void Solve()
{
    int Tc; cin >> Tc;
    for (int T = 1; T <= Tc; T++)
    {
        Initialize();
        Input();
        Solution();
 
        cout << "#" << T << " ";
        if (Answer == -1cout << GameOver << endl;
        else cout << Answer << endl;
    }
}
 
int main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
 
    //freopen("Input.txt", "r", stdin);
    Solve();
 
    return 0;
}
cs


+ Recent posts