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

 

 

사다리, 뱀의 수를 입력 받고 사다리의 정보를 의미하는 x, y 

뱀의 정보를 의미하는 u, v 를 입력 받아 마지막 칸에 도착할 때 까지 주사위를 굴리는 최소 횟수를 구한다.

풀이

최단 경로를 찾는 문제이므로 bfs 로 탐색해야 한다.
먼저 탐색은 1번째 칸에서 시작 한다 
다음칸으로 이동할 때 거리는 주사위로 정하므로 1~6 사이이다
따라서 현재칸 +1 ~ 현재칸 + 6 을 탐색한다.


여기서 고려해야 하는 건 뱀칸과 사다리 칸이 있는 경우다
뱀칸, 사다리 칸의 좌표는 map 에 따로 저장 했다가 해당 칸이 사다리 시작점이면 다음 칸을 사다리 끝점으로 지정한다.
제 코드에서는 뱀, 사다리를 분리해서 배열, map에 저장하고 처리 했는데 분리안하고 같이 처리해도 될것으로 보인다.

전체 코드

#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <queue>
#include <map>

using namespace std;
// 뱀과 사다리 게임

bool visited[101];
bool isladder[101];
bool issnake[101];

map<int, int> ladder;
map<int, int> snake;
int len[101];

void bfs(int n)
{
    visited[n] = true;
    queue <int> q;
    q.push(n);

    while (!q.empty())
    {
        int curr = q.front();
        q.pop();
        // 6칸탐색
        int nextmove = 0;
        for (int i = 1; i <= 6; i++)
        {
            nextmove = curr + i;
            if (nextmove <= 100)
            {
                // 사다리
                if (isladder[nextmove])
                {
                    nextmove = ladder[nextmove];
                }
                // 뱀
                if (issnake[nextmove])
                {
                    nextmove = snake[nextmove];
                }

                if (!visited[nextmove])
                {
                    visited[nextmove] = true;
                    q.push(nextmove);
                    len[nextmove] = len[curr] + 1;
                }
            }
        }
    }
}

int main() 
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n, m;
    // 사다리, 뱀의 수
    cin >> n >> m;

    // 사다리
    for (int i = 0; i < n; i++)
    {
        int x, y;
        cin >> x >> y;
        // 사다리 칸 여부
        isladder[x] = true;
        ladder[x] = y;
    }

    // 뱀
    for (int i = 0; i < m; i++)
    {
        int u, v;
        cin >> u >> v;
        // 뱀 칸 여부
        issnake[u] = true;
        snake[u] = v;
    }
    bfs(1);
    cout << len[100] << "\n";
}

'백준 > 골드' 카테고리의 다른 글

[백준 7576] - 토마토(C++)  (0) 2025.06.12

[백준 24446] - 알고리즘 수업 - 너비 우선 탐색 3 (실버2)

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

bfs(너비우선탐색) 문제로 우선 bfs 함수 구현하면 된다.

문제 조건에 따라 노드의 깊이는 -1로 초기화한다.

 

bfs 탐색 시 노드 깊이를 업데이트 한다. 

먼저 최초 방문 시 노드 깊이 = 0 으로 설정하고,

이후 queue 에서 탐색 하면서 다음 노드 깊이 = 현재 노드 깊이 +1 로 만든다.

 

이후 정점번호는 1부터임을 주의하며 1~ n 번 까지 정점의 깊이를 출력하면 된다.

 

예제 넣고 테스트 한 뒤 통과 확인

 

전체 코드

#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include <climits>
#include <queue>
#include <cstring>

using namespace std;

vector<int> vec[200001];
bool visited[200001];
int depth[200001];

void bfs(int n)
{
    queue<int> q;
    visited[n] = true;
    depth[n] = 0;
    q.push(n);

    for (int i = 0; i < vec[n].size(); i++)
    {
        q.push(vec[n][i]);
    }

    while (!q.empty())
    {
        int curr = q.front();
        q.pop();

        for (int i = 0; i < vec[curr].size(); i++)
        {
            int next = vec[curr][i];
            if (!visited[next])
            {
                q.push(next);
                visited[next] = true;
                depth[next] = depth[curr] + 1;
            }
        }
    }
}

int main() 
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m, r;
    cin >> n >> m >> r;

    // 노드 깊이 초기화
    for (int i = 1; i <= n; i++)
    {
        depth[i] = -1;
    }

    for (int i = 0; i < m; i++)
    {
        int u, v;
        cin >> u >> v;

        vec[u].push_back(v);
        vec[v].push_back(u);
    }

    bfs(r);

    for (int i = 1; i <= n; i++)
    {
        cout << depth[i] << "\n";
    }

    return 0;
}

+ Recent posts