BOJ 3055 탈출

2020. 11. 24. 00:52·알고리즘/BOJ

www.acmicpc.net/problem/3055

 

3055번: 탈출

사악한 암흑의 군주 이민혁은 드디어 마법 구슬을 손에 넣었고, 그 능력을 실험해보기 위해 근처의 티떱숲에 홍수를 일으키려고 한다. 이 숲에는 고슴도치가 한 마리 살고 있다. 고슴도치는 제

www.acmicpc.net

 

BFS 탐색 + 구현 문제였다.

고슴도치는 물이 들어올 곳에 갈 수 없다는 말에 처음에는 bfs 한 번에서 고슴도치와 물을 전부 pop 해가면서

했는데 그러한 접근은 while문이 한번 돌 때마다 하나씩 pop 되기 때문에 실패했다.

 

다시 생각해봤는데 물의 위치에서 BFS한 것과 고슴도치 위치에서 BFS 한 것을 통해서

고슴도치가 갈 위치 + 1 < 물이 들어올 위치값

을 만족한다면 고슴도치가 갈 수 있겠다는 생각이 들어서

BFS를 두 번 사용해서 구현했다.

 

1
2
3
4
5
6
7
8
9
    for (int i = 0; i < r; ++i) 
        for (int j = 0; j < c; ++j) {
            cin >> a[i][j];
            d2[i][j] = -1;
            d[i][j] = -1;
            if (a[i][j] == 'S') d[i][j] = 0, hh.push({ i,j });
            if (a[i][j] == '*') chk = true, d2[i][j] = 0, water.push({ i,j });
            if (a[i][j] == 'D') eX = i, eY = j;
        }
Colored by Color Scripter
cs

 

입력 부분인데 d는 고슴도치, d2는 물이 들어오는 시간을 체크해주기 위해 만들었다.

시작은 -1로 초기화해두고 S가 들어오면 고슴도치 큐에 넣어주고 *가 들어오면 물 큐에 넣어준다.

이후 D값의 위치를 eX eY에 담아준다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void bfs() {
    while (!water.empty()) {
        auto cur = water.front(); water.pop();
        for (int i = 0; i < 4; ++i) {
            int nx = cur.first + dx[i];
            int ny = cur.second + dy[i];
            if (nx < 0 || nx >= r || ny < 0 || ny >= c) continue;
            if (d2[nx][ny] == -1 && a[nx][ny] != 'X' && a[nx][ny] != 'D') {
                d2[nx][ny] = d2[cur.first][cur.second] + 1;
                water.push({ nx,ny });
            }
        }
    }
}
Colored by Color Scripter
cs

 

물에 대해서 BFS를 사용해주고

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void bfs2() {
    while (!hh.empty()) {
        auto cur = hh.front(); hh.pop();
        for (int i = 0; i < 4; ++i) {
            int nx = cur.first + dx[i];
            int ny = cur.second + dy[i];
            if (nx < 0 || nx >= r || ny < 0 || ny >= c) continue;
            if (d[nx][ny] == -1 && a[nx][ny] != 'X') {
                if (d[cur.first][cur.second] + 1 < d2[nx][ny] || d2[nx][ny] == -1) {
                    d[nx][ny] = d[cur.first][cur.second] + 1;
                    hh.push({ nx,ny });
                }
            }
        }
    }
}
Colored by Color Scripter
cs

 

고슴도치도 BFS를 사용해주는데 조심해야 할 점은 d[nx][ny] == -1 이 방문 처리하는 부분과

그 밑에 조건문을 같이 사용하면 방문 처리가 안돼서 메모리 초과나 런타임 에러가 나게 된다.

 

1
2
3
4
5
    bfs();
 
    if (!chk) fill(&d2[0][0], &d2[50][51], 1e9);
 
    bfs2();
Colored by Color Scripter
cs

 

물에 대해서 BFS를 사용했는데 만약 '*'이 없다면 시작 값이 -1이라 고슴도치에 대해 BFS 해줄 때 

d[cur.first][cur.second] + 1 < d2[nx][ny] 부분에서

만족을 못하기 때문에 고슴도치가 모든 구간에 접근할 수 있도록 물을 MAX처리해줬다.

 

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
#include <iostream>
#include <queue>
using namespace std;
 
char a[51][51];
int d[51][51], d2[51][51];
int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };
int r, c, eX, eY, ans;
bool chk;
queue<pair<int, int>> hh, water;
 
void bfs() {
    while (!water.empty()) {
        auto cur = water.front(); water.pop();
        for (int i = 0; i < 4; ++i) {
            int nx = cur.first + dx[i];
            int ny = cur.second + dy[i];
            if (nx < 0 || nx >= r || ny < 0 || ny >= c) continue;
            if (d2[nx][ny] == -1 && a[nx][ny] != 'X' && a[nx][ny] != 'D') {
                d2[nx][ny] = d2[cur.first][cur.second] + 1;
                water.push({ nx,ny });
            }
        }
    }
}
 
void bfs2() {
    while (!hh.empty()) {
        auto cur = hh.front(); hh.pop();
        for (int i = 0; i < 4; ++i) {
            int nx = cur.first + dx[i];
            int ny = cur.second + dy[i];
            if (nx < 0 || nx >= r || ny < 0 || ny >= c) continue;
            if (d[nx][ny] == -1 && a[nx][ny] != 'X') {
                if (d[cur.first][cur.second] + 1 < d2[nx][ny] || d2[nx][ny] == -1) {
                    d[nx][ny] = d[cur.first][cur.second] + 1;
                    hh.push({ nx,ny });
                }
            }
        }
    }
}
 
int main() {
    cin >> r >> c;
 
    for (int i = 0; i < r; ++i) 
        for (int j = 0; j < c; ++j) {
            cin >> a[i][j];
            d2[i][j] = -1;
            d[i][j] = -1;
            if (a[i][j] == 'S') d[i][j] = 0, hh.push({ i,j });
            if (a[i][j] == '*') chk = true, d2[i][j] = 0, water.push({ i,j });
            if (a[i][j] == 'D') eX = i, eY = j;
        }
 
    bfs();
 
    if (!chk) fill(&d2[0][0], &d2[50][51], 1e9);
 
    bfs2();
 
    if (d[eX][eY] != -1) cout << d[eX][eY] << endl;
    else cout << "KAKTUS" << endl;
 
    return 0;
}
Colored by Color Scripter
cs

 

 

'알고리즘 > BOJ' 카테고리의 다른 글

BOJ 1517 버블 소트  (0) 2020.11.26
BOJ 1005 ACM Craft  (0) 2020.11.25
16236 아기 상어  (0) 2020.11.22
BOJ 11048 이동하기  (0) 2020.11.20
BOJ 인내의 도미노 장인 호석  (0) 2020.11.19
'알고리즘/BOJ' 카테고리의 다른 글
  • BOJ 1517 버블 소트
  • BOJ 1005 ACM Craft
  • 16236 아기 상어
  • BOJ 11048 이동하기
khyu2
khyu2
  • khyu2
    dev log
    khyu2
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 알고리즘
        • BOJ
        • Programmers
        • Algorithm
        • SWEA
      • 개발
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    완전탐색
    피보나치 수
    이분탐색
    GREEDY
    이분 탐색
    구현
    피사노 주기
    행렬 제곱
    시뮬레이션
    BFS
    SWEA
    냅색
    팰린드롬
    우선순위 큐
    MST
    알고리즘
    프로그래머스
    소수
    트리
    dp
    다익스트라
    BOJ
    분할 정복
    완전 탐색
    조합
    유니온 파인드
    dfs
    크루스칼
    큐
    코딩테스트 연습
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
khyu2
BOJ 3055 탈출
상단으로

티스토리툴바