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

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

 

토마토가 들어 있는 상자를 입력 받아 모든 토마토가 익게 되는 최소 일수를 구하는 문제 이다.

상자의 가로, 세로 길이는 M, N 이고 익은 토마토는 1, 익지 않은 토마토는 0, 빈 칸은 -1 로 입력된다.

토마토가 모두 익지 못하는 경우는 -1로 출력 한다.

풀이

최단 경로 구하기므로 bfs 로 탐색 해야 한다. 탐색은 기준점에서 상, 하, 좌, 우 로 이루어진다.

먼저 고려해야할 점은 처음 입력될 때 익은 토마토가 2개 이상일 수 있는 것이다.

처음 시작 시 익은 토마토의 위치를 모두 큐에 넣고 탐색해야 한다.

그리고 토마토가 모두 익지 못하는 경우는 탐색을 끝낸 후

(입력받은 토마토가 있는 칸) 이면서 (방문 여부 = false) 인 경우로 판단 해 주었다.

토마토가 모두 익는 최소 일수는 맨 마지막에 일수만 저장한 배열에서 max() 를 활용해 찾는다.

(가장 늦게 걸린  토마토 익는 일수를 배열에서 찾음)

전체 코드

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

using namespace std;
int tomato[1001][1001];
bool visited[1001][1001];
int days[1001][1001];

int max_x = 0;
int max_y = 0;
void bfs(queue<pair<int, int>> &q)
{
    // 상 하 좌 우로 탐색
    int dirx[4] = { 0,0,-1,1 };
    int diry[4] = { 1,-1, 0,0 };

    while (!q.empty())
    {
        int curr_x = q.front().first;
        int curr_y = q.front().second;
        q.pop();

        for (int i = 0; i < 4; i++)
        {
            int currx = curr_x + dirx[i];
            int curry = curr_y + diry[i];
            if (currx >=0 && currx < max_x && curry >= 0 && curry < max_y)
            {
                if (!visited[currx][curry] && tomato[currx][curry] == 0)
                {
                    visited[currx][curry] = true;
                    q.push(make_pair(currx, curry));
                    days[currx][curry] = days[curr_x][curr_y] + 1;
                }
            }
        }
    }
}

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

    int n, m;
    cin >> m >> n;
    max_x = n;
    max_y = m;

    queue<pair<int, int>> q;

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            cin >> tomato[i][j];
            // 처음부터 토마토면 큐에 넣음
            if (tomato[i][j]== 1)
            {
                visited[i][j] = true;
                q.push(make_pair(i, j));
            }
        }
    }
    bfs(q);
    int max_day = 0;

    for (int i = 0; i < n; i++) 
    {
        for (int j = 0; j < m; j++) 
        {
            // 토마토 있는 칸인데 방문 못함
            if (visited[i][j] == false && tomato[i][j]==0) 
            {
                cout << -1;
                return 0;
            }
            // 가장 늦게 익는 토마토의 일수를 max 로 저장
            max_day = max(max_day, days[i][j]);
        }
    }
    cout << max_day;
}

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

[백준 16928] - 뱀과 사다리 게임(C++)  (1) 2025.06.27

+ Recent posts