[백준 3055번] 탈출

2017. 8. 9. 00:14알고리즘/백준

반응형




풀이


BFS로 풀면 되지만 조건 중에 고슴도치는 물이 찰 예정인 칸으로 이동할 수 없다고 되어있기 대문에 고슴도치의 이동보다 물의 이동이 항상 1만큼 빨라야한다.

그래서 BFS를 돌때 물을 먼저 1칸 이동후 고슴도치를 이동시키면 해결할 수 있다.







소스코드


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
#include <iostream>
using namespace std;
 
int se, ga;
char map[51][51];
int pos, des;
int que[10001], waterque[501][10001], posvisit[51][51= { 0, }, watervisit[51][51= { 0, };
int h, t, wh[501], wt[501];
 
void push(int a) {
    que[t++= a;
}
int pop() {
    return que[h++];
}
void wpush(int cnt, int a) {
    waterque[cnt][wt[cnt]++= a;
}
int wpop(int cnt) {
    return waterque[cnt][wh[cnt]++];
}
 
void wateroneHour(int hour) { // 함수 호출 1회당 물도 1칸 이동 
    while (wh[hour] != wt[hour]) {
        int wpos = wpop(hour);
        int wx = wpos / 1000;
        int wy = wpos % 1000;
 
        if (wx + 1 <= se - 1 && watervisit[wx + 1][wy] == 0 && map[wx+1][wy]=='.') {  // 아래
            watervisit[wx + 1][wy] = 1;
            map[wx + 1][wy] = '*';
            wpush(hour + 1, (wx + 1* 1000 + wy);
        }
        if (wx - 1 >= 0 && watervisit[wx - 1][wy] == 0 && map[wx - 1][wy] == '.') { // 위
            watervisit[wx - 1][wy] = 1;
            map[wx - 1][wy] = '*';
            wpush(hour + 1, (wx - 1* 1000 + wy);
        }
        if (wy + 1 <= ga - 1 && watervisit[wx][wy + 1== 0 && map[wx][wy + 1== '.') { // 오른쪽
            watervisit[wx][wy+1= 1;
            map[wx][wy+1= '*';
            wpush(hour + 1, wx * 1000 + wy+1);
        }
        if (wy - 1 >= 0 && watervisit[wx][wy - 1== 0 && map[wx][wy - 1== '.') { // 왼쪽
            watervisit[wx][wy - 1= 1;
            map[wx][wy - 1= '*';
            wpush(hour + 1, wx * 1000 + wy-1);
        }
    }
}
 
void bfs() {
    while (1) {
        int pos = pop();
        int x = pos / 1000;
        int y = pos % 1000;
 
        wateroneHour(posvisit[x][y] - 3);
 
        if ((x + 1 <= se - 1 && map[x + 1][y] == 'D'|| (x - 1 >= 0 && map[x - 1][y] == 'D'|| (y + 1 <= ga - 1 && map[x][y + 1== 'D'|| (y - 1 >= 0 && map[x][y - 1== 'D')) {
            cout << posvisit[x][y] -2 << '\n';
            return;
        }
 
        if (x + 1 <= se - 1 && posvisit[x + 1][y] == 0 && map[x + 1][y] == '.') {
            posvisit[x + 1][y] = posvisit[x][y]+1;
            push((x + 1* 1000 + y);
        }
        if (x - 1 >= 0 && posvisit[x - 1][y] == 0 && map[x - 1][y] == '.') {
            posvisit[x - 1][y] = posvisit[x][y] + 1;
            push((x - 1* 1000 + y);
        }
        if (y + 1 <= ga - 1 && posvisit[x][y+1== 0 && map[x][y+1== '.') {
            posvisit[x][y + 1= posvisit[x][y] + 1;
            push(x * 1000 + y + 1);
        }
        if (y - 1 >= 0 && posvisit[x][y - 1== 0 && map[x][y - 1== '.') {
            posvisit[x][y - 1= posvisit[x][y] + 1;
            push(x * 1000 + y - 1);
        }
        if (h == t) {
            cout << "KAKTUS" << '\n';
            break;
        }
    }
}
 
int main() {
    cin >> se >> ga;
    for (int i = 0; i < se; i++) {
        for (int j = 0; j < ga; j++) {
            cin >> map[i][j];
            if (map[i][j] == 'D')  // 비버굴 위치
                des = 1000 * i + j;
            else if (map[i][j] == 'S'// 고슴도치 위치
                pos = 1000 * i + j;
            else if (map[i][j] == '*'// 물 위치
                wpush(01000*+ j);
        }
    }
 
    posvisit[pos / 1000][pos % 1000= 3;
    push(pos);
    bfs();
 
    return 0;
}
cs


반응형

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

[백준 4883번] 삼각 그래프  (0) 2017.08.15
[백준 1057번] 토너먼트  (0) 2017.08.14
[백준 7490번] 0 만들기  (2) 2017.08.08
[백준 1992번] 쿼드트리  (2) 2017.08.01
[백준 9935번]문자열 폭발  (1) 2017.07.28