알고리즘 모음(C++)

백준 -6593 - 상범 빌딩(C++) 본문

백준

백준 -6593 - 상범 빌딩(C++)

공대생의 잡다한 사전 2021. 8. 10. 10:34

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

 

6593번: 상범 빌딩

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

www.acmicpc.net

6방향 탐색을 이용한 탐색 문제였습니다!

문제 조건
출력 예시

 

문제 접근 방법

1. 입력과 동시에 시작 위치를 저장한다.

2. 6방향 탐색을 통해서 갈 수 있는 곳을 찾는다 -> 이전에 방문하지 않았으면서, building[i][j] == '.'인 곳

3. 탐색 중, 출구에 도착한다면 -> 이동 횟수를, 도착하지 못한다면 -> -1를 return 한다

 

 

문제 접근 방법 - 2번 + 3번

int bfs() {
    queue<qu> q;
    q.push({ start.first.second, start.second, start.first.first, 0 });
    check[start.first.first][start.first.second][start.second] = 1;
    while (!q.empty()) {
        int x = q.front().x;
        int y = q.front().y;
        int z = q.front().z;
        int cnt = q.front().cnt;
        q.pop();
        if (building[z][x][y] == 'E') {
            return cnt;
        }
        for (int i = 0; i < 6; i++) {
            int xx = x + dx[i];
            int yy = y + dy[i];
            int zz = z + dz[i];
            if (xx >= 1 && xx <= R && yy >= 1 && yy <= C && zz >= 1 && zz <= L) {
                if (check[zz][xx][yy] == 0 && building[zz][xx][yy] != '#') {
                    check[zz][xx][yy] = 1;
                    q.push({ xx,yy,zz,cnt + 1 });
                }
            }
        }
    }
    return -1;
}

void solve() {
    int answer = bfs();
    if (answer == -1) cout << "Trapped!" << "\n";
    else printf("Escaped in %d minute(s).\n", answer);
}

탐색을 하는 BFS코드입니다

3차원 배열에는 높이(K), 행(R), 열(C) 순서대로 저장해야합니다.

int dx[6] = { 0,0,1,0,-1,0 };
int dy[6] = { 0,0,0,1,0,-1 };
int dz[6] = { 1,-1,0,0,0,0 };

6방향 탐색 배열입니다. Z축 위, Z축 아래, 상,하,좌,우를 탐색할 수 있습니다.

typedef struct qu {
    int x;
    int y;
    int z;
    int cnt;
}qu;

구조체에는 x, y, z축과 이동 횟수를 저장했습니다.

 

탐색의 경우의 수는 2가지입니다.

1. 출구에 도착했을 때 -> 현재 이동 횟수를 return 한다.

2. 출구에 도착하지 못했을 때 -> 6방향 탐색을 통해서 자신이 갈 수 있는 곳을 찾습니다(이전에 방문X,  building[z][x][y] == '.' 인곳) -> 찾은 후, 큐에 저장합니다. 

끝까지 출구에 도달하지 못했다면, -1을 return했습니다. answer는 return 값을 받은 변수입니다.  -> answer 값을 통해서 출력했습니다

 

 

자세한 것은 코드를 참고해주세요!

 

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#include <vector>
using namespace std;

int L, R, C;
char building[31][31][31];
int check[31][31][31];
int dx[6] = { 0,0,1,0,-1,0 };
int dy[6] = { 0,0,0,1,0,-1 };
int dz[6] = { 1,-1,0,0,0,0 };
pair<pair<int, int>, int> start;
typedef struct qu {
    int x;
    int y;
    int z;
    int cnt;
}qu;

int bfs() {
    queue<qu> q;
    q.push({ start.first.second, start.second, start.first.first, 0 });
    check[start.first.first][start.first.second][start.second] = 1;
    while (!q.empty()) {
        int x = q.front().x;
        int y = q.front().y;
        int z = q.front().z;
        int cnt = q.front().cnt;
        q.pop();
        if (building[z][x][y] == 'E') {
            return cnt;
        }
        for (int i = 0; i < 6; i++) {
            int xx = x + dx[i];
            int yy = y + dy[i];
            int zz = z + dz[i];
            if (xx >= 1 && xx <= R && yy >= 1 && yy <= C && zz >= 1 && zz <= L) {
                if (check[zz][xx][yy] == 0 && building[zz][xx][yy] != '#') {
                    check[zz][xx][yy] = 1;
                    q.push({ xx,yy,zz,cnt + 1 });
                }
            }
        }
    }
    return -1;
}

void solve() {
    int answer = bfs();
    if (answer == -1) cout << "Trapped!" << "\n";
    else printf("Escaped in %d minute(s).\n", answer);
} 

int main()
{
    cin.tie(0);
    cout.tie(0);
    while (1) {
        cin >> L >> R >> C;
        if (L == 0 && R == 0 && C == 0) break;
        for (int k = 1; k <= L; k++) {
            for (int i = 1; i <= R; i++) {
                for (int j = 1; j <= C; j++) {
                    cin >> building[k][i][j];
                    if (building[k][i][j] == 'S') {
                        start.first.first = k;
                        start.first.second = i;
                        start.second = j;
                    }
                }
            }
        }
        solve();
        memset(check, 0, sizeof(check));
    }
    return 0;
}

 

 

질문 및 조언 댓글 남겨주세요!

'백준' 카테고리의 다른 글

백준 1103 - 게임(C++, 복습)  (0) 2021.08.14
백준 14442 - 벽 부수고 이동하기 2(C++)  (0) 2021.08.10
백준 4179 - 불!(C++)  (0) 2021.08.09
백준 5427 - 불(C++)  (0) 2021.08.09
백준 1963 - 소수 경로(C++)  (0) 2021.08.09