반응형

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

 

13913번: 숨바꼭질 4

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일

www.acmicpc.net

<문제 풀이> BFS

https://www.acmicpc.net/problem/1697

 

1697번: 숨바꼭질

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일

www.acmicpc.net

숨바꼭질 문제에서 경로가 추가된 문제입니다.

parents 배열을 만들고 방문 체크를 하면서 cur -1, cur +1, 2 * cur의 부모를 cur로 만들고

cur == k가 되는 순간에 cur의 부모를 계속 따라가면서 배열에 저장하고 역순으로 출력하면 됩니다.

 

<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 <stack>
#include <utility>
#include <climits>
using namespace std;
 
int n, k; 
int visited[100001];
int dist[100001];
int parents[100001];
vector<int> res;
int bfs() {
    queue<int> Q;
    Q.push(n);
    visited[n] = true;
    dist[n] = 0;
    parents[n] = n;
    while (!Q.empty()) {
        int cur = Q.front(); Q.pop();
        if (cur == k) {
            int s = cur;
            while (parents[s] != s) {
                res.push_back(s);
                s = parents[s];
            }
            res.push_back(s);
            return dist[cur];
        }
        if (2 * cur <= 100000 && !visited[2 * cur]) {
            Q.push(2 * cur);
            visited[2 * cur] = true;
            dist[2 * cur] = dist[cur] + 1;
            parents[2 * cur] = cur;
        }
        if (cur - 1 >= 0 && !visited[cur - 1]) {
            Q.push(cur - 1);
            visited[cur - 1= true;
            dist[cur - 1= dist[cur] + 1;
            parents[cur - 1= cur;
        }
        if (cur + 1 <= 100000 && !visited[cur + 1]) {
            Q.push(cur + 1);
            visited[cur + 1= true;
            dist[cur + 1= dist[cur] + 1;
            parents[cur + 1= cur;
        } 
    }
}
 
int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
 
    cin >> n >> k;
 
    cout << bfs() <<'\n';
    int len = res.size();
    for (int i = len - 1; i >= 0; i--) {
        cout << res[i] << " ";
    }
    return 0;
}
 
cs
반응형

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

[백준 17071번] 숨바꼭질 5  (0) 2021.11.25
[백준 12851번] 숨바꼭질2  (0) 2021.11.22
[백준 6593번] 상범 빌딩  (0) 2021.11.19
[백준 5014번] 스타트링크  (0) 2021.11.19
[백준 2146번] 다리 만들기  (0) 2021.11.19
반응형

문제 링크: 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

+ Recent posts