반응형

문제 링크: https://www.acmicpc.net/problem/6593

 

6593번: 상범 빌딩

당신은 상범 빌딩에 갇히고 말았다. 여기서 탈출하는 가장 빠른 길은 무엇일까? 상범 빌딩은 각 변의 길이가 1인 정육면체(단위 정육면체)로 이루어져있다. 각 정육면체는 금으로 이루어져 있어

www.acmicpc.net

<문제 풀이> BFS

BFS로 dx, dy 방향으로 최단거리를 구하는 문제에서 dz 방향이 추가된 문제입니다. 

3차원 배열 입력과, dz방향 추가만 고려하면 구현하는 건 2차원과 동일합니다.

int dx[6= { 0,01-100 }; //동 서 남 북 상 하
int dy[6= { 1,-1000 , 0 };
int dz[6= { 0000 , 1-1 };

<C++ 소스 코드>

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
#include <iostream>
#include <string>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <utility>
#include <climits>
using namespace std;
 
int dx[6= { 0,01-100 }; //동 서 남 북 상 하
int dy[6= { 1,-1000 , 0 };
int dz[6= { 0000 , 1-1 };
 
char building[30][30][30];
int visited[30][30][30];
 
int L, R, C;
class pos {
public:
    int z;
    int x;
    int y;
    pos(int z, int x, int y) : z(z), x(x), y(y) {
    }
};
 
int bfs() {
    queue<pos> Q;
    for (int z = 0; z < L; z++) {
        for (int x = 0; x < R; x++) {
            for (int y = 0; y < C; y++) {
                if (building[z][x][y] == 'S') {
                    Q.push({ z, x, y });
                    visited[z][x][y] = 1;
                }
            }
        }
    }
    while (!Q.empty()) {
        auto cur = Q.front(); Q.pop();
        if (building[cur.z][cur.x][cur.y] == 'E') { //Escaped
            return visited[cur.z][cur.x][cur.y] - 1;
        }
        for (int dir = 0; dir < 6; dir++) {
            int nz = cur.z + dz[dir];
            int nx = cur.x + dx[dir];
            int ny = cur.y + dy[dir];
            if (nx < 0 || ny < 0 || nz < 0 || nz >= L ||nx >= R || ny >= C ) continue;
            if (building[nz][nx][ny] == '#' || visited[nz][nx][ny]) continue;
            visited[nz][nx][ny] = visited[cur.z][cur.x][cur.y] + 1;
            Q.push({ nz, nx, ny });
        }
    }
    return -1//Trapped!
}
 
void reset() {
    for (int z = 0; z < L; z++) {
        for (int x = 0; x < R; x++) {
            for (int y = 0; y < C; y++) {
                building[z][x][y] = 0;
                visited[z][x][y] = 0;
            }
        }
    }
}
int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
   
    while (true) {
        cin >> L >> R >> C;
        if (L == 0 && R == 0 && C == 0break;
        for (int z = 0; z < L; z++) {
            for (int x = 0; x < R; x++) {
                for (int y = 0; y < C; y++) {
                    cin >> building[z][x][y];
                }
            }
        }
        int res = bfs();
        if (res == -1) {
            cout << "Trapped!\n";
        }
        else {
            cout << "Escaped in " << res << " minute(s).\n";
        }
        reset();
    }
    return 0;
}
 
cs

 

 

반응형

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 12851번] 숨바꼭질2  (0) 2021.11.22
[백준 13913번] 숨바꼭질4  (0) 2021.11.21
[백준 5014번] 스타트링크  (0) 2021.11.19
[백준 2146번] 다리 만들기  (0) 2021.11.19
[백준 5427번] 불  (0) 2021.11.17
반응형

문제 링크: https://www.acmicpc.net/problem/5014

 

5014번: 스타트링크

첫째 줄에 F, S, G, U, D가 주어진다. (1 ≤ S, G ≤ F ≤ 1000000, 0 ≤ U, D ≤ 1000000) 건물은 1층부터 시작하고, 가장 높은 층은 F층이다.

www.acmicpc.net

<문제 풀이>

기본적인 그래프 BFS를 구현하면 되는 문제입니다 

다음 정점의 위치는 다음과 같습니다.

위층: cur + U

아래층: cur - D

<C++ 소스 코드>

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
#include <iostream>
#include <string>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <utility>
#include <climits>
using namespace std;
 
int F, S, G, U, D;
 
int visited[1000001];
 
int bfs() {
    queue<int> Q;
    Q.push(S);
    visited[S] = 1;
    while (!Q.empty()) {
        int cur = Q.front(); Q.pop();
        if (cur == G) return visited[cur] - 1;
        if (cur + U <= F && !visited[cur + U]) {
            Q.push(cur + U);
            visited[cur + U] = visited[cur] + 1;
        }
        if (cur - D >= 1 && !visited[cur - D]) {
            Q.push(cur - D);
            visited[cur - D] = visited[cur] + 1;
        }
    }
    return -1//use the stairs
}
 
int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> F >> S >> G >> U >> D;
    int res = bfs();
    if (res == -1) {
        cout << "use the stairs";
    }
    else {
        cout << res;
    }
    return 0;
}
 
cs

 

반응형

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 13913번] 숨바꼭질4  (0) 2021.11.21
[백준 6593번] 상범 빌딩  (0) 2021.11.19
[백준 2146번] 다리 만들기  (0) 2021.11.19
[백준 5427번] 불  (0) 2021.11.17
[백준 7562번] 나이트의 이동  (0) 2021.11.16
반응형

문제 링크:https://www.acmicpc.net/problem/2146

 

2146번: 다리 만들기

여러 섬으로 이루어진 나라가 있다. 이 나라의 대통령은 섬을 잇는 다리를 만들겠다는 공약으로 인기몰이를 해 당선될 수 있었다. 하지만 막상 대통령에 취임하자, 다리를 놓는다는 것이 아깝다

www.acmicpc.net

<문제 풀이> BFS

섬의 육지에서 시작해서 BFS로 다른 섬의 육지에 최초로 만나는 지점이 다리를 놓을 수 있는 방법 중에 하나입니다.

그래서 문제를 해결하기 위해서

1. bfs로 섬을 구분한다. 

10
1 1 1 0 0 0 0 2 2 2
1 1 1 1 0 0 0 0 2 2
1 0 1 1 0 0 0 0 2 2
0 0 1 1 1 0 0 0 0 2
0 0 0 1 0 0 0 0 0 2
0 0 0 0 0 0 0 0 0 2
0 0 0 0 0 0 0 0 0 0
0 0 0 0 3 3 0 0 0 0
0 0 0 0 3 3 3 0 0 0
0 0 0 0 0 0 0 0 0 0

2. i번째 섬의 모든 육지를 큐에 담고 최초로 다른 섬과 만날 때까지 최단거리를 갱신한다.

-> 모든 섬에 대해서 bfs를 돌리고 최솟값을 구하면 됩니다. 

 

<C++ 소스 코드>

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
#include <iostream>
#include <string>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <utility>
#include <climits>
using namespace std;
 
#define X first
#define Y second
 
int board[100][100];
int visited1[100][100]; // 섬 구분
int visited2[100][100]; // 최단 거리
int dx[4= { 010-1 };
int dy[4= { 1 , 0-10 };
 
int n;
int flag = 1;
int res = INT_MAX;
 
void bfs1() {// 섬 구분
    queue<pair<intint> > Q;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (board[i][j] == 1 && !visited1[i][j]) {
                Q.push({ i, j });
                visited1[i][j] = true;
                board[i][j] = flag;
                while (!Q.empty()) {
                    auto cur = Q.front(); Q.pop();
                    for (int dir = 0; dir < 4; dir++) {
                        int nx = cur.X + dx[dir];
                        int ny = cur.Y + dy[dir];
                        if (nx < 0 || ny < 0 || nx >= n || ny >= n)continue;
                        if (board[nx][ny] != 1 || visited1[nx][ny])continue;
                        Q.push({ nx, ny });
                        board[nx][ny] = flag;
                        visited1[nx][ny] = true;
                    }
                }
                flag++;
            }
        }
    }
    flag--;
}
 
void bfs2() { //최단거리
    flag = 1;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (board[i][j] == flag) {
                queue<pair<intint> > Q;
                Q.push({ i, j });
                visited2[i][j] = 1;
                while (!Q.empty()) {
                    auto cur = Q.front(); Q.pop();
                    for (int dir = 0; dir < 4; dir++) {
                        int nx = cur.X + dx[dir];
                        int ny = cur.Y + dy[dir];
                        if (nx < 0 || ny < 0 || nx >= n || ny >= n)continue;
                        if (visited2[nx][ny] && visited2[nx][ny] <= visited2[cur.X][cur.Y] + 1)continue;
                        if (board[nx][ny] == flag) {
                            visited2[nx][ny] = 1;
                            Q.push({ nx, ny });
                        }
                        else if (board[nx][ny] == 0) {
                            visited2[nx][ny] = visited2[cur.X][cur.Y] + 1;
                            Q.push({ nx, ny });
 
                        }
                        else if (board[nx][ny] != flag) {
                            res = min(res, visited2[cur.X][cur.Y] - 1);
                          
                        }
                    }
                }
                flag++;
                fill(&visited2[0][0], &visited2[99][100], 0);
            }
        }
    }
}
int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> board[i][j];
        }
    }
    bfs1();
    bfs2();
    cout << res;
    return 0;
}
 
cs

 

반응형

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 6593번] 상범 빌딩  (0) 2021.11.19
[백준 5014번] 스타트링크  (0) 2021.11.19
[백준 5427번] 불  (0) 2021.11.17
[백준 7562번] 나이트의 이동  (0) 2021.11.16
[백준 10026번] 적록색약  (0) 2021.11.05
반응형

문제 링크: https://www.acmicpc.net/problem/5427

 

5427번: 불

상근이는 빈 공간과 벽으로 이루어진 건물에 갇혀있다. 건물의 일부에는 불이 났고, 상근이는 출구를 향해 뛰고 있다. 매 초마다, 불은 동서남북 방향으로 인접한 빈 공간으로 퍼져나간다. 벽에

www.acmicpc.net

<문제 풀이> BFS

이 문제는 4179번 문제에서 테스트 케이스가 추가된 문제입니다.

각 테스트 케이스마다 배열을 초기화하는 작업만 추가하면 됩니다.

https://seokjin2.tistory.com/67

 

[백준 4179번] 불!

문제 링크:https://www.acmicpc.net/problem/4179 4179번: 불! 입력의 첫째 줄에는 공백으로 구분된 두 정수 R과 C가 주어진다. 단, 1 ≤ R, C ≤ 1000 이다. R은 미로 행의 개수, C는 열의 개수이다. 다음 입력으..

seokjin2.tistory.com

<C++ 소스 코드>

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
#include <iostream>
#include <string>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <utility>
#include <climits>
using namespace std;
 
#define X first
#define Y second
int dx[4= { 010-1 };
int dy[4= { 1 , 0-10 };
 
char board[1000][1000];
int fire[1000][1000];
int person[1000][1000];
int w, h;
void f_bfs() {
    queue<pair<intint> >Q;
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            if (board[i][j] == '*') {
                Q.push({ i, j });
                fire[i][j] = 1;
            }
        }
    }
    while (!Q.empty()) {
        auto cur = Q.front(); Q.pop();
        for (int dir = 0; dir < 4; dir++) {
            int nx = cur.X + dx[dir];
            int ny = cur.Y + dy[dir];
            if (nx < 0 || ny < 0 || nx >= h || ny >= w)continue;
            if (board[nx][ny] == '#' || fire[nx][ny])continue;
            fire[nx][ny] = fire[cur.X][cur.Y] + 1;
            Q.push({ nx, ny });
        }
    }
}
int p_bfs() {
    f_bfs();
    queue<pair<intint> >Q;
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            if (board[i][j] == '@') {
                Q.push({ i, j });
                person[i][j] = 1;
            }
        }
    }
    while (!Q.empty()) {
        auto cur = Q.front(); Q.pop();
        for (int dir = 0; dir < 4; dir++) {
            int nx = cur.X + dx[dir];
            int ny = cur.Y + dy[dir];
            if (nx < 0 || ny < 0 || nx >= h || ny >= w) { // 탈출 성공
                return person[cur.X][cur.Y];
            }
            if (board[nx][ny] == '#' || (person[cur.X][cur.Y] + 1 >= fire[nx][ny] && fire[nx][ny])  || person[nx][ny])continue//벽 또는 불 때문에 이동 못하는 경우
            person[nx][ny] = person[cur.X][cur.Y] + 1;
            Q.push({ nx, ny });
        }
    }
    return 0// 탈출 실패
}
 
int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int test_case; cin >> test_case;
    while (test_case--) {
        cin >> w >> h;
        for (int i = 0; i < h; i++) {
            string s; cin >> s;
            for (int j = 0; j < w; j++) {
                board[i][j] = s[j];
            }
        }
        int res = p_bfs();
        if (res) cout << res << '\n';
        else cout << "IMPOSSIBLE\n";
 
        fill(&fire[0][0], &fire[999][1000], 0);
        fill(&person[0][0], &person[999][1000], 0);
 
    }
    return 0;
}
 
cs

 

반응형

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 5014번] 스타트링크  (0) 2021.11.19
[백준 2146번] 다리 만들기  (0) 2021.11.19
[백준 7562번] 나이트의 이동  (0) 2021.11.16
[백준 10026번] 적록색약  (0) 2021.11.05
[백준 4179번] 불!  (0) 2021.11.04
반응형

문제 링크:https://www.acmicpc.net/problem/7562

 

7562번: 나이트의 이동

체스판 위에 한 나이트가 놓여져 있다. 나이트가 한 번에 이동할 수 있는 칸은 아래 그림에 나와있다. 나이트가 이동하려고 하는 칸이 주어진다. 나이트는 몇 번 움직이면 이 칸으로 이동할 수

www.acmicpc.net

 

<문제 풀이> BFS

기본적인 BFS 최단거리 문제랑 똑같은데 방향만 8방향으로 설정해주면 됩니다.

int dx[8] = {-2, -1, 1, 2, -2, -1, 1, 2};
int dy[8] = {-1, -2, -2, -1, 1, 2, 2, 1};

 

<C++ 소스 코드>

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
#include <iostream>
#include <string>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <utility>
#include <climits>
using namespace std;
 
#define X first
#define Y second
 
int dx[8= {-2-112-2-112};
int dy[8= {-1-2-2-11221};
int visited[300][300];
 
int bfs(int n, int cx, int cy, int wx, int wy) {
    queue<pair<intint> > Q;
    Q.push({ cx, cy });
    visited[cx][cy] = 0;
    if (cx == wx && cy == wy) return visited[wx][wy];
    while (!Q.empty()) {
        auto cur = Q.front(); Q.pop();
        cx = cur.X;
        cy = cur.Y;
        for (int dir = 0; dir < 8; dir++) {
            int nx = cx + dx[dir];
            int ny = cy + dy[dir];
            if (nx < 0 || ny < 0 || nx >= n || ny >= n) continue;
            if (visited[nx][ny] != -1continue;
            Q.push({ nx, ny });
            visited[nx][ny] = visited[cx][cy] + 1;
            if (nx == wx && ny == wy) return visited[wx][wy];
        }
    }
}
 
int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int test_case; cin >> test_case;
    while (test_case--) {
        int n; cin >> n;
        int cx, cy; cin >> cx >> cy;
        int wx, wy; cin >> wx >> wy;
        fill(&visited[0][0], &visited[299][300], -1);
        cout << bfs(n, cx, cy, wx, wy)<<'\n';
    }
  
    return 0;
}
 
cs

 

 

반응형

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 2146번] 다리 만들기  (0) 2021.11.19
[백준 5427번] 불  (0) 2021.11.17
[백준 10026번] 적록색약  (0) 2021.11.05
[백준 4179번] 불!  (0) 2021.11.04
[백준 7576번] 토마토  (0) 2021.11.03
반응형

문제 링크:https://www.acmicpc.net/problem/10026

 

10026번: 적록색약

적록색약은 빨간색과 초록색의 차이를 거의 느끼지 못한다. 따라서, 적록색약인 사람이 보는 그림은 아닌 사람이 보는 그림과는 좀 다를 수 있다. 크기가 N×N인 그리드의 각 칸에 R(빨강), G(초록)

www.acmicpc.net

<문제 풀이>

정상인에 대해서 BFS를 돌리고, 적록색약에 대해서 BFS를 돌리면 되는데

적록색약은 빨간색과 초록색을 같은 색으로 보니깐 board[i][j]의 값이 R이면 G로 바꿔준 뒤 BFS를 돌리면 됩니다.

 

<C++ 소스 코드>

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
#include <iostream>
#include <string>
#include <algorithm>
#include <queue>
#include <vector>
#include <utility>
using namespace std;
 
#define X first
#define Y second
 
char board[100][100];
bool visited[100][100];
int dx[4= { 10-10 };
int dy[4= { 0-101 };
int n;
int bfs() {
    int cnt = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (!visited[i][j]) {
                cnt++;
                queue<pair<intint>> Q;
                Q.push({ i,j });
                while (!Q.empty()) {
                    auto cur = Q.front(); Q.pop();
                    for (int dir = 0; dir < 4; dir++) {
                        int nx = cur.X + dx[dir];
                        int ny = cur.Y + dy[dir];
                        if (nx < 0 || ny < 0 || nx >= n || ny >= n)continue;
                        if (board[cur.X][cur.Y] != board[nx][ny] || visited[nx][ny]) continue//다른 색이면 무시
                        Q.push({ nx, ny });
                        visited[nx][ny] = true;
 
                    }
                }
            }
        }
    }
    return cnt;
}
//적록 색약은 빨간색과 초록색이 같은색
void change_R_to_G() {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (board[i][j] == 'R') board[i][j] = 'G';
        }
    }
}
int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n;
    for (int i = 0; i < n; i++) {
        string s; cin >> s;
        int s_len = s.size();
        for (int j = 0; j < s_len; j++) {
            board[i][j] = s[j];
        }
    }
    cout << bfs() << ' ';
    change_R_to_G();
    fill(&visited[0][0], &visited[99][100], 0);
    cout << bfs();
    return 0;
}
 
cs

 

반응형

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 5427번] 불  (0) 2021.11.17
[백준 7562번] 나이트의 이동  (0) 2021.11.16
[백준 4179번] 불!  (0) 2021.11.04
[백준 7576번] 토마토  (0) 2021.11.03
[백준 4949번] 균형잡힌 세상  (0) 2021.11.01
반응형

문제 링크:https://www.acmicpc.net/problem/4179

 

4179번: 불!

입력의 첫째 줄에는 공백으로 구분된 두 정수 R과 C가 주어진다. 단, 1 ≤ R, C ≤ 1000 이다. R은 미로 행의 개수, C는 열의 개수이다. 다음 입력으로 R줄동안 각각의 미로 행이 주어진다.  각각의 문

www.acmicpc.net

 

<문제 풀이> BFS 알고리즘

이문제는 여러 개의 시작점을 갖는 불에 대해서 BFS를 먼저 돌려서 불의 도착 시간을 구한 뒤에, BFS를 사용해서 각 위치에 대해서 지훈이가 불 보다 먼저 갈 수 있으면 그 위치에 지훈이의 도착 시간을 갱신하면 됩니다.

 

여러 개의 시작점을 갖는 불을 동시에 BFS로 출발시키는 방법은 처음 시작점을 모두 큐에 넣고 기본적인 BFS을 진행하면 됩니다.

 

지훈이가 불 보다 먼저 갈 수 있는지 확인하는 방법은 현재 위치에서 (지훈이의 도착 시간 + 1) < (불의 도착 시간)이면 지훈이가 불 보다 먼저 갈 수 있습니다. (2차원 visited 배열 2개가 필요)

 

그리고 next 좌표가 배열의 범위를 넘어가면 지훈이가 탈출에 성공한 거니깐 지훈이의 도착 시간을 return 하면 됩니다.

만약 큐의 원소가 모두 비게 되면 지훈이의 위치가 한 번도 배열의 범위를 못 넘은 거니깐 지훈이는 탈출에 실패한 게 됩니다.

 

<C++ 소스 코드>

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
#include <iostream>
#include <utility>
#include <queue>
using namespace std;
 
#define X first
#define Y second
 
char board[1000][1000];
int F_dist[1000][1000];
int J_dist[1000][1000];
int dx[4= {10-10};
int dy[4= {0-101};
int r, c;
 
void F_bfs() {
    queue<pair<intint> > Q;
    for (int i = 0; i < r; i++) {
        for (int j = 0; j < c; j++) {
            if (board[i][j] == 'F') {
                Q.push({ i, j });
                F_dist[i][j] = 1;
            }
        }
    }
    while (!Q.empty()) {
        auto cur = Q.front(); Q.pop();
        for (int dir = 0; dir < 4; dir++) {
            int nx = cur.X + dx[dir];
            int ny = cur.Y + dy[dir];
            if (nx < 0 || ny < 0 || nx>=|| ny >= c) continue;
            if (board[nx][ny] == '#' || F_dist[nx][ny])continue;
            Q.push({ nx,ny });
            F_dist[nx][ny] = F_dist[cur.X][cur.Y] + 1;
        }
    }
}
 
int J_bfs() {
    F_bfs();
    queue<pair<intint> > Q;
    for (int i = 0; i < r; i++) {
        for (int j = 0; j < c; j++) {
            if (board[i][j] == 'J') {
                Q.push({ i, j });
                J_dist[i][j] = 1;
            }
        }
    }
    while (!Q.empty()) {
        auto cur = Q.front(); Q.pop();
        for (int dir = 0; dir < 4; dir++) {
            int nx = cur.X + dx[dir];
            int ny = cur.Y + dy[dir];
            if (nx < 0 || ny < 0 || nx >= r || ny >= c) {//범위를 넘어가면 탈출 성공
                return J_dist[cur.X][cur.Y]; 
            }
            if (board[nx][ny] == '#' || J_dist[nx][ny])continue;
            if (J_dist[cur.X][cur.Y] + 1 >= F_dist[nx][ny] && F_dist[nx][ny]) continue//불이 더 빨리 도착하면 무시
            Q.push({ nx,ny });
            J_dist[nx][ny] = J_dist[cur.X][cur.Y] + 1;
        }
    }
    return -1;
}
 
int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> r >> c;
    for (int i = 0; i < r; i++) {
        for (int j = 0; j < c; j++) {
            cin >> board[i][j];
        }
    }
    int res = J_bfs();
    if (res != -1cout << res;
    else cout << "IMPOSSIBLE";
 
 
    return 0;
}
 
cs

 

반응형

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 7562번] 나이트의 이동  (0) 2021.11.16
[백준 10026번] 적록색약  (0) 2021.11.05
[백준 7576번] 토마토  (0) 2021.11.03
[백준 4949번] 균형잡힌 세상  (0) 2021.11.01
[백준 5430번] AC  (0) 2021.10.28
반응형

문제 링크:https://www.acmicpc.net/problem/7576

 

7576번: 토마토

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N이 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M,N ≤ 1,000 이다. 둘째 줄부터는 하나의 상자에 저장된 토마토

www.acmicpc.net

 

<문제 풀이> BFS

이문제는 기본적인 bfs를 사용해서 최단거리를 구하면 됩니다.

 

그런데 익은 토마토가 여러 개이면 모든 익은 토마토에 대해서 동시에 출발을 해야 됩니다.

 

시작점을 여러개 두고 bfs를 동시에 진행하는 방법은

시작점을 모두 queue에 넣고 시작하면 됩니다. (그러면 번갈아가면서 push, pop을 하기 때문에 동시에 출발시킨 효과)

 

 

<C++ 소스 코드>

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
#include <iostream>
#include <algorithm>
#include <utility>
#include <queue>
#include <string>
using namespace std;
 
#define X first
#define Y second
 
int box[1000][1000];
int visited[1000][1000];
int dx[4= {1 ,0-10};
int dy[4= {0-101};
int n, m;
 
 
void bfs() {
    queue<pair<intint> > Q;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (box[i][j] == 1) {
                Q.push({ i,j });
            }
            if (box[i][j] == 0) {
                visited[i][j] = -1;
            }
        }
    }
    
    while (!Q.empty()) {
        auto cur = Q.front(); Q.pop();
        for (int dir = 0; dir < 4; dir++) {
            int nx = cur.X + dx[dir];
            int ny = cur.Y + dy[dir];
            if (nx < 0 || ny <0 || nx>=|| ny >=m) continue;
            if (visited[nx][ny] >= 0continue;
            Q.push({ nx, ny });
            visited[nx][ny] = visited[cur.X][cur.Y] + 1;
        }
    }
    
}
 
int cal_res() {
    int res = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (visited[i][j] == -1return -1;
            res = max(res, visited[i][j]);
        }
    }
    return res;
}
 
int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
 
    cin >> m >> n;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> box[i][j];
        }
    }
    bfs();
   
    cout << cal_res();
    return 0;
}
 
cs
반응형

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 10026번] 적록색약  (0) 2021.11.05
[백준 4179번] 불!  (0) 2021.11.04
[백준 4949번] 균형잡힌 세상  (0) 2021.11.01
[백준 5430번] AC  (0) 2021.10.28
[백준 2164번] 카드2  (0) 2021.10.27

+ Recent posts